ROS2 Tutorial: Robotic Arm

URDF Description

File arm.urdf.xacro contains links to the files that actually do the job. The only thing I would like to mention is the joint that attaches the robotic hand to the world:


Here, world is the environment described in .world or .sdf, while base_0 is the bottom segment of our robot. Just think of a sheet of the plywood and a robotic arm screwed to it.

The most important of files the arm.urdf.xacro links to is armA_core.xacro. It contains the URDF describing the robotic arm.


This is a standard beginning of an URDF file. Note that I am calling the model armA, while the project is arm_01. Same armA can be further enchanced in arm_02 and so on.


This are controllers. I am going to explain them below.


As I mentioned in the introduction, this project is largely inspired by a wonderful site of David Valencia. The idea with namespace is taken from there and it probably can be used if we create multiple robotic arms. At the moment it is not used, but let's keep it.

base_0 is the first (bottom one) segment of the robotic arm. It doesn't move either (as in our project) relative to the world, or relative to the robot the arm is attached to.

<inertial> tag. This tag describes the mass-related properties of a link. Mass is defined in kilograms, with center of mass located in the origin point. Then we have the 3x3 rotational inertia matrix. Since this is symmetrical, it can be represented by only 6 elements:

ixx ixy ixz
ixy iyy iyz
ixz iyz izz

So, what is the inertia matrix? Let's quote Wiki:

This information can be provided to you by modeling programs such as MeshLab. The inertia of geometric primitives (cylinder, box, sphere) can be computed using Wikipedia's list of moment of inertia tensors (and is used in the above example). The inertia tensor depends on both the mass and the distribution of mass of the object. A good first approximation is to assume equal distribution of mass in the volume of the object and compute the inertia tensor based on the object's shape, as outlined above. If unsure what to put, a matrix with ixx/iyy/izz=1e-3 or smaller is often a reasonable default for a mid-sized link (it corresponds to a box of 0.1 m side length with a mass of 0.6 kg). The identity matrix is a particularly bad choice, since it is often much too high (it corresponds to a box of 0.1 m side length with a mass of 600 kg!).
When using realtime controllers, inertia elements of zero (or almost zero) can cause the robot model to collapse without warning, and all links will appear with their origins coinciding with the world origin.

A <visual> tag is responsible for the looks of our link, this is where we want to use the mesh. Note that, if you use the trick with "tiny, almost invisible extra bits of mesh" described above (or some other, similar tricks), or if you set different x,y,z for different visual tags, you can use multiple visual tags in one link, with different meshes, and they will be shifted relative to each other. In this project I am not going to use this approach.

scale tag looks a bit strange. This is because there seems to be no way to specify units in STL file. Yes, when you do 3d printing, it works, but just because they have "treat as millimeters" or something like that in their software. Otherwise, a 400 mm object will be treated as a 400 m one. My model has a 40 mm object (in Tinkercad), and a 0.004 scale, which gives us 40 m * 0.004 = 16 cm. As for size in Tinkercad - it does not have to be the robot's real size, because Gazebo's working area has limited size (1x1x1 meter max), so it is better to scale robot down while working in Tinkercad, and then scale it back up using scale tag.

Note the material tag - it specifies color of an object in RViz. Gazebo uses different colors, and we will see corresponding tags below, in this same file.

Finally, a <collision> tag. It looks similar to visual, except that sometimes we can simplify it for the sake of speed of simulation, using primitives instead of meshes.

Now let's take a look at the first joint of the robotic arm.


Above (in a meshes section), I have already explained how to save meshes so that two links are properly connected by a joint. The height of a base_0 link is 11.4 cm, so we need to raise (along Z) the second object, and as they are symmetric (along X and Y), we can simply provide 0,0 as joint's X and Y origin.

The axis tag specifies the axis along which child object rotates, in our case it is Z. Additional limit tag sets max. force (Newtons) and limit angles. The later is especially useful in our case, as our design doesn't allow unlimited rotation (well, considering that power will be supplied to arm's motors via wires, you can not spin the hand as if it was a fan, even if mechanical design allows it).

The "dynamics" element is part of the URDF description, and applies to the damping and friction in a joint. Friction doesn't, probably, require clarification. The physical damping (optional, defaults to 0) value of the joint (in newton-seconds per metre [N*s/m] for prismatic joints, in newton-metre-seconds per radian [N*m*s/rad] for revolute joints). Damping, in physics, restraining of vibratory motion, such as mechanical oscillations, noise, and alternating electric currents, by dissipation of energy. Unless a child keeps pumping a swing, its motion dies down because of damping. Shock absorbers in automobiles and carpet pads are examples of damping devices.

I am going to skip the rest of links and joints. The way I saved meshes and calculated their origins in URDF was explained in "meshes" section.


The last part of a armA_core.xacro file specifies which Gazebo color corresponds to which link. Obviously, it is a good idea to make sure Gazebo colors correspond to RViz ones.


(C), all rights reserved

Please read the disclaimer