Skip to content
  • Home
  • About the Blog
  • About the Author
  • Sitemap

Abdur Rosyid's Blog

Just a few notes on mechanical engineering and robotics

Writing Hardwara Interface Node

July 15, 2021 by Abdur Rosyid

The Big Picture

The following shows the big picture of how to use ros_control with either simulation or a real robot. It can be seen in the picture that the class “hardware_interface::RobotHW” should be implemented in a hardware interface node when ros_control is used with a real robot. On the other hand, the class “hardware_interface::RobotHWSim” should be implemented when ros_control is used with simulation in Gazebo.

In a real robot, the hardware interface node reads the joint state (joint sensor data) and writes control commands to the embedded controller which subsequently control the actuators in real-time.

In Gazebo simulation, the implementation of “hardware_interface::RobotHWSim” reads from the simulated sensor and writes control command to the simulated actuators. You don’t need to write a hardware interface node if you use ros_control with Gazebo simulation.

Picture Credit: http://gazebosim.org/tutorials/?tut=ros_control

Using ros_control with a custom real robot

If you have an off-the-shelf ROS-enabled robot, the connection between ros_control and the robot’s hardware is already established. However, if you have a custom robot and you want to use ros_control to control the robot, then you need to write a hardware interface node which sits between the hardware_interface components of ros_control and the control hardware (i.e. actuators and sensors) of the custom robot.

The main control loop when using ros_control with a real robot can be illustated in the picture below:

Picture Credit: https://roscon.ros.org/2014/wp-content/uploads/2014/07/ros_control_an_overview.pdf

The three main tasks being done in the control loop is:

  • reading the joint state
  • updating the control loop all the time
  • writing control commands to the actuator

Some examples of hardware interface nodes can be found in the following links:

  • http://wiki.ros.org/ros_control/Tutorials/Create%20your%20own%20hardware%20interface
  • https://medium.com/@slaterobotics/how-to-implement-ros-control-on-a-custom-robot-748b52751f2e; https://github.com/SlateRobotics/tr1_hardware_interface
  • https://sir.upc.edu/projects/rostutorials/10-gazebo_control_tutorial/index.html#hardware-abstraction-layer
  • https://www.rosroboticslearning.com/ros-control
  • https://cse400.luciochen.com/codes/HardwareInterface.html#building-a-c-node
  • https://github.com/PickNikRobotics/ros_control_boilerplate
  • https://github.com/eborghi10/my_ROS_mobile_robot/tree/e04acfd3e7eb4584ba0aab8a969a74d6c30eed34

The following is a simple example of a hardware interface node as provided in ROS Wiki. In this example, the robot having two actuated joints namely A and B uses JointStateInterface and PositionJointInterface. Actually, the robot can also additionally use, for example, VelocityJointInterface and many more interfaces.

The main function shows clearly that the three main tasks of the control loop are performed: reading, updating, and writing.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <hardware_interface/joint_command_interface.h>
#include <hardware_interface/joint_state_interface.h>
#include <hardware_interface/robot_hw.h>
 
class MyRobot : public hardware_interface::RobotHW
{
public:
  MyRobot()
{
   // connect and register the joint state interface
   hardware_interface::JointStateHandle state_handle_a("A", &pos[0], &vel[0], &eff[0]);
   jnt_state_interface.registerHandle(state_handle_a);
 
   hardware_interface::JointStateHandle state_handle_b("B", &pos[1], &vel[1], &eff[1]);
   jnt_state_interface.registerHandle(state_handle_b);
 
   registerInterface(&jnt_state_interface);
 
   // connect and register the joint position interface
   hardware_interface::JointHandle pos_handle_a(jnt_state_interface.getHandle("A"), &cmd[0]);
   jnt_pos_interface.registerHandle(pos_handle_a);
 
   hardware_interface::JointHandle pos_handle_b(jnt_state_interface.getHandle("B"), &cmd[1]);
   jnt_pos_interface.registerHandle(pos_handle_b);
 
   registerInterface(&jnt_pos_interface);
  }
 
private:
  hardware_interface::JointStateInterface jnt_state_interface;
  hardware_interface::PositionJointInterface jnt_pos_interface;
  double cmd[2];
  double pos[2];
  double vel[2];
  double eff[2];
};
 
main()
{
  MyRobot robot;
  controller_manager::ControllerManager cm(&robot);
 
  while (true)
  {
     robot.read();
     cm.update(robot.get_time(), robot.get_period());
     robot.write();
     sleep();
  }
}

Notice that the hardware interface needs to load before the controller manager or the manager will likely crash.

Post navigation

Previous Post:

ROS_Control

Next Post:

ROS Controllers for Manipulator

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Categories

  • STEM 101
  • Robotics
  • Kinematics
  • Dynamics
  • Control
  • Robot Operating System (ROS)
  • Robot Operating System (ROS2)
  • Software Development
  • Mechanics of Materials
  • Finite Element Analysis
  • Fluid Mechanics
  • Thermodynamics

Recent Posts

  • Pull Request on Github
  • Basics of Git and Github
  • Conda vs Docker
  • A Conda Cheat Sheet
  • Installing NVIDIA GPU Driver on Ubuntu

Archives

  • June 2025
  • July 2021
  • June 2021
  • March 2021
  • September 2020
  • April 2020
  • January 2015
  • April 2014
  • March 2014
  • March 2012
  • February 2012
  • June 2011
  • March 2008
© 2026 Abdur Rosyid's Blog | WordPress Theme by Superbthemes