The code for this section is located in arm_03 part of an archive. Note that archive includes some additional folders, like maps and worlds, that are used by all projects and therefore are located outside of them. Also note that we use ROS2 Galactic.
In a previous chapter, we have created a simple Gripper to attach to the end of our Robotic Arm. However, if you test it on a real task of picking a small object, you will find that there is a huge problem with this design: it does not work.
When gripper tries to hold an object (say, a small cube), it begins vibrating, and no mater what friction you specified in your URDF, the cube will slide off the grip.
The reason for this problem is simple: position controller can not handle the situation, period. You need effort controller or maybe velocity controller. This is what you will find after 10 minutes of Internet search.
After another 60 minutes, you will suspect that it is not that easy. There is no single example of how to do it, and if you spend few more hours, you will find that in ROS2 this functionality is "not completely implemented". Maybe. It never say so directly. Really sad that ROS2 developers spend man-decades writing code and then man-minutes writing tutorials, if any.
Anyway, at the moment of this writing there are few people in the Internet who mentioned that "it worked", and no code to support this statement. What should we do?
We look for workarounds. After all, the problem exists for many years, sure there should be some...
First of all, there is a school of thought suggesting that we need to create a fixed joint between gripper and object - dynamically. There is only one problem with it: you need to create a Gazebo plugin to do that. Yes, Gasebo does not expose such interfaces.
It was done in ROS1, and as far as I know, nothing was ported to ROS2. Except, MAYBE, for MoveIt, that MIGHT have such functionality. No promices, no tutorials.
Another approach is to use an existing vacuum_gripper Gazebo control. Unfortunately, it doesn't have cleas tutorials, but it looks like it can not provide strong enough "suction". You can find online projects that used 9 grippers together to lift a reasonably heavy object. So we are not going this path either.
The reason I listed all above is for you to not be surpriced by all those strange things I am about to introduce. There is literally no way to do that simple task in an easy way using these friendly tools (sarcasm).
Here is what we are going to do.
1. Close gripper on some object.
2. Detect contact and make sure it is not contact of gripper's elements to one another.
3. Read the object's position in the gripper's frame.
4. Stop gripper from closing any further (and if you think it is easy, think twice: this is ROS2!). Because, if we do not stop it, it will start vibrating.
5. As long as gripper is closed, set this position back to these coordinates, by a 50 Hz timer. So if gripper moves (because arm moves), object will move with it.
As you can see, quick and dirty.