Adding a custom gripper attached to a ZA6

Hello!
I have added a custom gripper to my za6. I have created a xacro file for it and adjusted the za6_macro.xacro file to add the gripper to the robot when my tool is specified. I have also adjusted all the yaml files, srdf files, and launch files necessary to get my gripper showing in rviz when I launch the robot. I ran the moveit setup assistant and edited all those files to make new planning groups so I can also plan and execute move_group goals relative to links on my gripper rather than only links on the base robot. I can also control my gripper, but I am not currently using ros_control to do so.

The system is now telling me that it does not know the states of all joints (referring to the two joints in my gripper), so the next step is obviously to get the current state of my gripper joints into the ros system.

Here is my current understanding:

  1. hal_ros_control (which the za6 uses) extends the ideas of ros_control in that there is a hardware_interface::RobotHW instance running which controllers can use to interface with and command the robot and get the state of the robot.
  2. hal_ros_control creates the required node with configuration files using the machinekit-hal system.
  3. hal_hw_interface is the realtime node created by the configuration files that is running and producing the joint states and accepting commands to control the arm.
  4. ros_control has (or maybe had, see below) a limitation that there can only be one and only one hardware_interface::RobotHW instance running, so I can’t just make a second node to interface to only my gripper.

Based on that, I can see 3 possibilities right now (though someone may have a better idea):

  1. there’s some way to get my (485 modbus controlled) gripper actuators controlled/read through the machinekit-hal system. I haven’t found any examples of how to do this.
  2. there’s a possibility that I can somehow use combined_robot_hw to combine my interface with the za6 hal interface into one single node as plugins. (Ref1, Ref2) Concerns: I don’t need realtime for my node but I don’t see how the realtime could be a plugin with something that isn’t realtime. I also don’t know how this would work since hal_ros_control doesn’t seem to launch in a standard way. As I understand it, hal_mgr uses sytem calls to straight rosrun things and calls system calls somehow to run hal_hw_interface
  3. I could use a joint state publisher and aggregate the JointState messages from my gripper and the rest of the arm to produce one single JointState message comprised of all joints in the system. Concerns: This seems to be discouraged or at least non-typical. Also, since the hal_hw_interface node is not launched in a standard way, I don’t know how to remap the topics to make this work. Also, going through another node, I wonder if the timing of messages might lead to issues.

I know that tormach has used grippers attached to the arm, but it looks like those are controlled via ethercat. Is there any guidance on which way I should choose? I very much appreciate any help or recommendations or corrections.

Thank you!

1 Like

@tbh
Thank you for posting this and providing useful references.

What is your motivation behind keeping both robot joints and gripper joints controlled via a ros_control? Could you share a practical use case? Do you just want to see the gripper state changing in Moveit and Rviz, such that its solid body is correctly used in the collision checking?

As far as unifying both of them in a single controller, I can only think of pure convenience of sending comands to a single topic/service, or a complex manipulation scenario where the gripper closing action has to be in sync with current robot motion, e.g. begin closing the gripper before pickup goal for robot is reached. This is obviously beyond the scope of our current development directions. I am curious to hear what is your use case if that can be shared.

We did have some internal tests with 485 modbus-controlled grippers. Some of those were controlled via a separate Python3 ros package that created the ROS action interface. Actuator states of the servo moving the gripper jaws were fetched and published to the JointState topic that was recognized by MoveIt and linked to the URDF joints, collision objects and visualization . I honestly recommend going this route and just having an independent package for gripper.

Regarding the possibilities you mentioned:

  1. Getting RS485 data via a custom Machinekit HAL component and exposing the data as HAL pins is a big learning curve and would require extensive domain knowledge and breaking the configs we support. I think that not all of the required software is published to achieve that.
  2. I don’t know if combined_robot_hw is going to work well. @John_Morris what do you think?
  3. Republishing JointState topic seems to be a hacky way to tackle this. You will introduce delays and would have to handle phase shifts between both robot and gripper JointStates. You could interpolate both sources based on their message timestamps, and then sample at known intervals, but this way you never get the true recorded state.

I followed the github issue topic you provided and several others. In the end of the thread you provided, one user stated that the expected functonality of several hardware interfaces became indeed accessible in ROS kinetic ros-controls issue #75 comment.

I am happy to follow up on this.

@Jakub_Kaminski Thanks for getting back to me!

My main use case is indeed for collision checking, but also just for getting the robot to work and not whine with constant error messages when one of its fundamental assumptions is invalid. I don’t need coordinated control with the arm at this point (we’d probably have to get different actuators if so). But I do need moveit to recognize the state of the gripper so we can get faster and smoother move plans without having to go to extra safe poses.

I did initially try to go with independent control, but the system did not seem very happy with me doing that and thus I made an investigation into how to integrate.

When I first added my gripper to the robot model, I only added the urdf/srdf and didn’t include any kind of interface node that published the state or took commands. There were error messages constantly saying something to the effect that the complete robot state was not known. We already have a lot of code in the ROS ecosystem, so we will not be using pathpilot in the end, but we are using it in this initial phase and for jogging around the arm and whatnot. I have since closed that container and changed the code, but if I remember correctly, it was almost impossible to do anything due to pathpilot constantly switching to the status screen to display error messages.

I next tried to publish the states of my gripper joints on the same JointState topic that the robot uses since the joints are all named. That apparently helped some things, as there were no (or at least not the same constant) error messages, but pathpilot was not totally happy with that either. The section where it displays all the joint states was flashing between two different numbers since there were two publishers of the same topic and I didn’t use that as I wasn’t sure if it was safe to use the robot in that way.

That was when I started investigating a single unified JointState message. I didn’t see how I could easily add my joints to the topic published by the Hal node nor how to remap the topics so I could inject my joint states since it’s not launched traditionally. We have not used ros_control in the past, but the more I read, the more ubiquitous it seems to be in the ROS community so I started looking there. It looks to be an assumption that if you are using moveit, then you are most likely using ros_control. I know that it says that any node that implements a follow trajectory action server would work, but there are quite a lot of references to ros_control in the docs. Further, there are things we might use in the future like the pick and place pipeline, grasps and the task constructor that all involve grippers and while I have not investigated too deeply, I imagine that the original writers probably use ros_control. It is also appealing that the nav stack (which we intend to work with in the future) also just works with ros_control so all the same code would just work. I am still figuring out moveit and investigating ros_control, but it still seems that the assumption is that there is one single robot_hw, thus my question.

But for right now, I would be very happy to simply have the system know my gripper joint states and to be able to control the gripper not with ros_control. When you used your 485 modbus gripper, did you just publish to the same topic? Is pathpilot okay with that?

I’m not sure what was wrong with my launch the other time. I have retried having a separate custom node publish the states of the joints in my gripper on the same topic as the hal node, /joint_states, and it is working fine now. moveit still plans and pathpilot seems unaffected so I can still jog.