ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

building a custom hardware interface for MoveIt

asked 2019-08-22 13:09:44 -0500

schlitz0hr gravatar image

updated 2022-01-22 16:10:03 -0500

Evgeny gravatar image

Hello, I struggle building a hardware Interface for my custom build 6-axis robot. I've already build everything for the robot, so there is a topic published, containing all the measured angles from the encoders and I have another topic, on which my robot is subscribed to, where I can publish positions that are then executed by the robot.

Using the fake_controller, I can move the robot without listening to my encoders, so I would like to use ros_controls with a predefined controller. I do know that I need a hardware interface which provides the controller with current positions and takes the commands, calculated by the controller and publish them to my robots command topic.

But how? Where is my hardware interface located, what do I need to change in my demo.launch etc. I read a lot of tutorials, but neither one did answer my questions. I would be very thankfull to see someones moveit setup with a custom robot.

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted

answered 2019-08-23 10:47:22 -0500

ffusco gravatar image


A brief list of what you would need to do:

  1. Implement a hardware interface to move your robot. You can follow this tutorial and also this. You will likely have to expose a PositionJointInterface for the joints of your robot, since you mentioned that you can send desired positions. The interface will "live" in a package of its own.

  2. Make sure that you can move the robot using simple controllers, such as position_controllers/JointGroupPositionController. If controllers are working properly, you should be able to move the robot simply by publishing into a topic. If you can do this, 95% of the work is done.

  3. Load and start a Joint Trajectory Controller. It will start a FollowJointTrajectory action server. This is the "connection" used by MoveIt to send commands to your real robot.

  4. Follow this MoveIt tutorial. It shows how to "instruct" MoveGroup to locate the controller you created. Just to be clear, in the MoveIt controllers.yaml file you have to give the full name, including namespaces for the controller. As an example, if your controller is named trajectory_controller, but runs in the namespace my_robot, then the parameter name will be my_robot/trajectory_controller.

  5. Do not launch demo.launch from your MoveIt configuration file. Instead, make a copy of that and change it so that trajectory execution is allowed. As far as I remember, you will have to change the parameters given to the joint_state_publisher (so that it listens to the correct topic) and change the argument fake_execution to false when including the main MoveGroup launch file. I do not remember if you have to do other changes, sorry. In any case, that should be all! :)

edit flag offensive delete link more


Thank you for your help! I think one problem were the namespaces, but now it works! Nevertheless I am still a bit confused wether the joint trajectory position controller is the right controller. The real robot state is displayed in moveit, so when I move the robot by hand, it is also moving in the visualisation, but the execution does not match the planned trajectory, especially if there are any Interruptions. So if I say go to position 200 and the sensor only senses 180, there will not be any correction made to the goal position?

schlitz0hr gravatar image schlitz0hr  ( 2019-09-03 03:18:16 -0500 )edit

Sorry, I did not fully get your question, would you mind rephrasing it? In particular I do not get what you mean with "I say go to position 200 and the sensor only senses 180": do you mean something like "what happens if I plan, then move the robot manually without MoveIt, and finally ask to execute the path that was planned in the beginning?".

In any case, think to the trajectory controller as a simple "bridge" between MoveIt and your bot: you ask MoveIt to plan from point A to B. The plan creates intermediate steps C1, C2, etc, each with an associated time T1, T2, ... . You then ask the controller to execute the motion, which will make sure that the robot properly follows in space and time the given trajectory, so that, eg, at time T3 it will say to the robot to be in C3. Note that ...(more)

ffusco gravatar image ffusco  ( 2019-09-03 07:15:06 -0500 )edit

I hope the last part helps you understanding better why the trajectory controller might be the right controller. If you feel like it is not the case, you can of course use other strategies!

ffusco gravatar image ffusco  ( 2019-09-03 07:19:13 -0500 )edit

Hi ffusco, I'm going through a similar issue with the OP, except that now I have managed to set up my hardware_interface node to communicate with my Arduino through the rosserial, which accepts a joint_position_controller. I have also managed to set up my Moveit-Gazebo connection, which is communicating through a FollowJointTrajectoryAction and JointTrajectoryController, and I can get Moveit to control the robot arm in RViz and Gazebo.

Is there any way of allowing hardware_interface to communicate directly with the FollowJointTrajectoryAction? Is this an issue with namespaces, or do I have to implement an intermediate controller between joint_position_controller and joint_trajectory_controller?

Sorry if this is a silly question, I'm quite new to ROS :S

wootoodoo gravatar image wootoodoo  ( 2020-06-09 03:03:53 -0500 )edit

I have never used arduino with ros, so I do not know exactly how you can set it up. However, in general, if you use ros control most of the times you define and load multiple controllers at once, starting only those that are actually required at a specific time. As an example, it is rather common to load a position controller for one or more joints and a joint trajectory controller at the same time. Then, you just need to switch between the two as needed. Most likely, you'll start the position controller(s) and command the joints "manually" via the proper topic, then switch to the trajectory controller and let, e.g., MoveIt plan and forward the execution request. This is the general working principle, but perhaps your setup is different. Referring to your question "Is there any way of allowing hardware_interface to communicate directly with the ...(more)

ffusco gravatar image ffusco  ( 2020-06-09 04:42:37 -0500 )edit

Actually, it should be the other way around: it's the hardware that "spawns" the action server, and MoveIt should simply "connect" to it :) I don't know if this answers you, since I don't know your full setup. If you need further details, feel free to comment below. Just give me few more details about the ros connections you have and I'll try to clarify if possible ;)

ffusco gravatar image ffusco  ( 2020-06-09 04:45:10 -0500 )edit

Thanks for the quick response!

I've got a feeling the issue is in how I spawn my controllers, here is my controller.yaml that I spawn in the Moveit package:

controller_manager_ns: controller_manager


  • name: six_dof_arm/six_dof_arm_joint_controller

    action_ns: follow_joint_trajectory

    type: FollowJointTrajectory

    default: true


    • shoulder_pan_joint
    • shoulder_pitch_joint
    • elbow_pitch_joint
    • wrist_pitch_joint
    • gripper_roll_joint
  • name: six_dof_arm/gripper_controller

    action_ns: follow_joint_trajectory

    type: FollowJointTrajectory

    default: true


    • finger_joint1
    • finger_joint2
wootoodoo gravatar image wootoodoo  ( 2020-06-09 07:58:15 -0500 )edit

Here is the controller.yaml that I spawn at the hardware_interface package




  type: joint_state_controller/JointStateController
  publish_rate: 50

    type: position_controllers/JointPositionController
    joint: shoulder_pan_joint
    pid: {p: 10.0, i: 0.0, d: 1.0}
    type: position_controllers/JointPositionController
    joint: shoulder_pitch_joint
    pid: {p: 10.0, i: 0.0, d: 1.0}
    type: position_controllers/JointPositionController
    joint: elbow_pitch_joint
    pid: {p: 10.0, i: 0.0, d: 1.0}
    type: position_controllers/JointPositionController
    joint: wrist_pitch_joint
    pid: {p: 10.0, i: 0.0, d: 1.0}
    type: position_controllers/JointPositionController
    joint: gripper_roll_joint
    pid: {p: 10.0, i: 0.0, d:
wootoodoo gravatar image wootoodoo  ( 2020-06-09 07:58:59 -0500 )edit

Question Tools

1 follower


Asked: 2019-08-22 13:09:44 -0500

Seen: 2,242 times

Last updated: Jun 18 '20