-
Notifications
You must be signed in to change notification settings - Fork 7
Design a robot arm in ROS
The standard way to define a robot within the ROS ecosystem is with URDF.
ℹ️ The Unified Robotics Description Format (URDF) is an XML specification to model multi-body systems, such as robotic manipulators and mobile robots. URDF is "unified" because allows to specify multiple properties:
- kinematic chain structure
- visual appearance (shape and colour)
- collision zones
- physical properties (dynamics, inertia, contact coefficients, etc)
- other elements, such as controllers and plug-ins
ℹ️ The main elements (or tags) of interest are <robot>
, <link>
and <joint>
, which are nested in a hierarchical structure. <link>
and <joint>
are children of the <robot>
element, conversely <robot>
is a parent of the other two elements.
<robot>
<link>
...
</link>
<link>
...
</link>
<joint>
...
</joint>
</robot>
ℹ️ Each <link>
represent one part of the robot structure, and defines its properties (colour, shape, mass, etc).
ℹ️ Each <joint>
defines how links are connected to one another.
simple_robot.urdf.xacro
inside RBT1001/src/week3/description/urdf/
. This is an empty file for now.
<robot name="simple_robot" xmlns:xacro="http://www.ros.org/wiki/xacro">
<link name="world"/>
<link name="base_link"> <!-- Each link should have a name to distinguish and refer to them -->
<visual>
<geometry>
<box size="0.2 0.2 0.2"/> <!-- This specifies the shape of the link -->
</geometry>
<material name="base_material"> <!-- You need to give a name to the material -->
<color rgba="0.5 0.5 0.5 1"/> <!-- This specifies the color of the link -->
</material>
</visual>
</link>
<link name="link_1">
<visual>
<geometry>
<cylinder length="0.6" radius="0.1"/>
</geometry>
<material name="link1_material">
<color rgba="0 1 0 1"/>
</material>
</visual>
</link>
<joint name="fixed" type="fixed"> <!-- it's a fixed frame because we do not want the base to move -->
<parent link="world"/> <!-- parent, because in the chain sequence comes before the child -->
<child link="base_link"/> <!-- This is the child, connected by the joint to the parent -->
</joint>
<joint name="base_to_link_1" type="continuous"> <!-- Continuous, meaning it can rotate without upper/lower limits -->
<parent link="base_link"/>
<child link="link_1"/>
</joint>
</robot>
ros2 launch week3 view_robot.launch.py description_file:=simple_robot.urdf.xacro
. We can also move the angle of the joint we defined by moving the slider in the joint_state_publisher_gui
window.
- We have a
world
link which is just a reference for where our robot should be anchored.
<link name="world"/>
- We defined the base of the robot as
base_link
to be a gray box-shaped component:
<link name="base_link"> <!-- Each link should have a name to distinguish and refer to them -->
<visual>
<geometry>
<box size="0.2 0.2 0.2"/> <!-- This specifies the shape of the link -->
</geometry>
<material name="base_material"> <!-- You need to give a name to the material -->
<color rgba="0.5 0.5 0.5 1"/> <!-- This specifies the color of the link -->
</material>
</visual>
</link>
- We defined a part of the robot arm as
link_1
to be a green cylinder:
<link name="link_1">
<visual>
<geometry>
<cylinder length="0.6" radius="0.1"/>
</geometry>
<material name="link1_material">
<color rgba="0 1 0 1"/>
</material>
</visual>
</link>
- ❗ Now, we have defined our joints. The first is fixing the robot base to the world (simply saying that our robot base does not move):
<joint name="fixed" type="fixed"> <!-- it's a fixed frame because we do not want the base to move -->
<parent link="world"/> <!-- parent, because in the chain sequence comes before the child -->
<child link="base_link"/> <!-- This is the child, connected by the joint to the parent -->
</joint>
- ❗ And, we define how the arm moves with respect to the base:
<joint name="base_to_link_1" type="continuous"> <!-- Continuous, meaning it can rotate without upper/lower limits -->
<parent link="base_link"/>
<child link="link_1"/>
</joint>
continuous here essentially means that it is a rotational joint.
<link name="base_link">
<visual>
<origin xyz="0 0 0.1" rpy="0 0 0"/><!-- !! ADD THIS to offset the position of the box's centre-->
<geometry>
<box size="0.2 0.2 0.2"/>
</geometry>
...
</link>
<link name="link_1">
<visual>
<origin xyz="0 0 0.3" rpy="0 0 0"/> <!-- !! ADD THIS to offset the position of the cylinder's centre-->
<geometry>
<cylinder length="0.6" radius="0.1"/>
</geometry>
...
</link>
view_robot
node from the terminal (CTRL+C), and relaunch it to see what is the result!
<joint name="base_to_link_1" type="continuous">
<origin xyz="0 0 0.2" rpy="${pi/2} 0 0"/> <!-- !! ADD THIS to rotate and offset the link (not its geometry) -->
<axis xyz="0 1 0"/> <!-- !! ADD THIS for setting the axis of rotation. By default rotation is on the x axis-->
<parent link="base_link"/>
<child link="link_1"/>
</joint>
view_robot
node from the terminal (CTRL+C), and relaunch it to see what is the result!
Parts for the workshops are extracted, edited from and/or inspired by the following sources.
- Official ROS humble tutorials: https://docs.ros.org/en/humble/Tutorials.html
- Elephant Robotics docs: https://docs.elephantrobotics.com/docs/gitbook-en/