Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GZ Docs #35

Merged
merged 16 commits into from
Jul 1, 2024
19 changes: 19 additions & 0 deletions ur_simulation_gz/doc/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
ur_simulation_gz
================

This package contains configurations and example files for Gazebo simulation of Universal Robots manipulators.

Structure of the repository
---------------------------

To set up the simulation the used files are:

- ``urdf/ur_gz.ros2_control.xacro`` - macro for ros2_control configuration, defining the initial joint positions and the hardware interface plugin for the simulation
- ``urdf/ur_gz.urdf.xacro`` - main file that contains the robot description, defines reference for the Gazebo world and initializes ros2_control Gazebo plugin.

.. toctree::
:maxdepth: 2
:caption: Contents:

installation
usage
49 changes: 49 additions & 0 deletions ur_simulation_gz/doc/installation.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
Installation
============

Skip any of below steps is not applicable.

Setup ROS2 Workspace
--------------------

1. Create a colcon workspace:

.. code-block:: console

$ export COLCON_WS=~/workspaces/ur_gz
$ mkdir -p $COLCON_WS/src

.. note::
Feel free to change ``~/workspaces/ur_gz`` to whatever absolute path you want.

.. note::

Over time you will probably have multiple ROS workspaces, so it makes sense to them all in a subfolder.

Also, it is good practice to put the ROS version in the name of the workspace, for different tests you could just add a suffix to the base name ``ur_gz``.

2. Download the required repositories and install package dependencies:

.. code-block:: console

$ cd $COLCON_WS
$ git clone -b ros2 https://github.com/UniversalRobots/Universal_Robots_ROS2_GZ_Simulation.git src/ur_simulation_gz
$ vcs import --input src/ur_simulation_gz/ur_simulation_gz-not-released.rolling.repos src # only required for rolling
$ rosdep update && rosdep install --ignore-src --from-paths src -y

Configure and build Workspace
-----------------------------

To configure and build the workspace execute following commands:

.. code-block:: console

$ source /opt/ros/rolling/setup.bash # necessary after installing gz-sim-vendor
$ cd $COLCON_WS
$ colcon build --symlink-install

and finally source your workspace before launching anything else

.. code-block:: console

$ source $COLCON_WS/install/setup.bash
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
158 changes: 158 additions & 0 deletions ur_simulation_gz/doc/resources/test_world.sdf
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
<sdf version='1.10'>
<world name='default'>
<gravity>0 0 -9.8000000000000007</gravity>
<magnetic_field>5.5644999999999998e-06 2.2875799999999999e-05 -4.2388400000000002e-05</magnetic_field>
<atmosphere type='adiabatic'/>
<physics type='ode'>
<max_step_size>0.001</max_step_size>
<real_time_factor>1</real_time_factor>
<real_time_update_rate>1000</real_time_update_rate>
</physics>
<scene>
<ambient>0.400000006 0.400000006 0.400000006 1</ambient>
<background>0.699999988 0.699999988 0.699999988 1</background>
<shadows>true</shadows>
</scene>
<model name='charmander'>
<pose>0.29999999999999999 1 0.050000000000000003 0 0 0</pose>
<link name='box_link'>
<inertial>
<inertia>
<ixx>0.16666</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>0.16666</iyy>
<iyz>0</iyz>
<izz>0.16666</izz>
</inertia>
<mass>1</mass>
<pose>0 0 0 0 0 0</pose>
</inertial>
<collision name='box_collision'>
<geometry>
<box>
<size>0.050000000000000003 0.050000000000000003 0.050000000000000003</size>
</box>
</geometry>
<surface>
<friction>
<ode/>
</friction>
<bounce/>
<contact/>
</surface>
</collision>
<visual name='box_visual'>
<geometry>
<box>
<size>0.050000000000000003 0.050000000000000003 0.050000000000000003</size>
</box>
</geometry>
<material>
<ambient>0.300000012 0.300000012 0.300000012 1</ambient>
<diffuse>0.699999988 0.699999988 0.699999988 1</diffuse>
<specular>1 1 1 1</specular>
</material>
</visual>
<pose>0 0 0 0 0 0</pose>
<enable_wind>false</enable_wind>
</link>
<static>true</static>
<self_collide>false</self_collide>
</model>
<model name='bulbasaur'>
<pose>0 1 0.050000000000000003 0 0 0</pose>
<link name='box_link'>
<inertial>
<inertia>
<ixx>0.16666</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>0.16666</iyy>
<iyz>0</iyz>
<izz>0.16666</izz>
</inertia>
<mass>1</mass>
<pose>0 0 0 0 0 0</pose>
</inertial>
<collision name='box_collision'>
<geometry>
<box>
<size>0.050000000000000003 0.050000000000000003 0.050000000000000003</size>
</box>
</geometry>
<surface>
<friction>
<ode/>
</friction>
<bounce/>
<contact/>
</surface>
</collision>
<visual name='box_visual'>
<geometry>
<box>
<size>0.050000000000000003 0.050000000000000003 0.050000000000000003</size>
</box>
</geometry>
<material>
<ambient>0.300000012 0.300000012 0.300000012 1</ambient>
<diffuse>0.699999988 0.699999988 0.699999988 1</diffuse>
<specular>1 1 1 1</specular>
</material>
</visual>
<pose>0 0 0 0 0 0</pose>
<enable_wind>false</enable_wind>
</link>
<static>true</static>
<self_collide>false</self_collide>
</model>
<model name='squirtle'>
<pose>-0.29999999999999999 1 0.050000000000000003 0 0 0</pose>
<link name='box_link'>
<inertial>
<inertia>
<ixx>0.16666</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>0.16666</iyy>
<iyz>0</iyz>
<izz>0.16666</izz>
</inertia>
<mass>1</mass>
<pose>0 0 0 0 0 0</pose>
</inertial>
<collision name='box_collision'>
<geometry>
<box>
<size>0.050000000000000003 0.050000000000000003 0.050000000000000003</size>
</box>
</geometry>
<surface>
<friction>
<ode/>
</friction>
<bounce/>
<contact/>
</surface>
</collision>
<visual name='box_visual'>
<geometry>
<box>
<size>0.050000000000000003 0.050000000000000003 0.050000000000000003</size>
</box>
</geometry>
<material>
<ambient>0.300000012 0.300000012 0.300000012 1</ambient>
<diffuse>0.699999988 0.699999988 0.699999988 1</diffuse>
<specular>1 1 1 1</specular>
</material>
</visual>
<pose>0 0 0 0 0 0</pose>
<enable_wind>false</enable_wind>
</link>
<static>true</static>
<self_collide>false</self_collide>
</model>
</world>
</sdf>
37 changes: 37 additions & 0 deletions ur_simulation_gz/doc/resources/ur_controllers_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
controller_manager:
ros__parameters:
update_rate: 500 # Hz

joint_state_broadcaster:
type: joint_state_broadcaster/JointStateBroadcaster

joint_trajectory_controller:
type: joint_trajectory_controller/JointTrajectoryController


joint_trajectory_controller:
ros__parameters:
joints:
- alice_shoulder_pan_joint
- alice_shoulder_lift_joint
- alice_elbow_joint
- alice_wrist_1_joint
- alice_wrist_2_joint
- alice_wrist_3_joint
command_interfaces:
- position
state_interfaces:
- position
- velocity
state_publish_rate: 100.0
action_monitor_rate: 20.0
allow_partial_joints_goal: false
constraints:
stopped_velocity_tolerance: 0.2
goal_time: 0.0
alice_shoulder_pan_joint: { trajectory: 0.2, goal: 0.1 }
alice_shoulder_lift_joint: { trajectory: 0.2, goal: 0.1 }
alice_elbow_joint: { trajectory: 0.2, goal: 0.1 }
alice_wrist_1_joint: { trajectory: 0.2, goal: 0.1 }
alice_wrist_2_joint: { trajectory: 0.2, goal: 0.1 }
alice_wrist_3_joint: { trajectory: 0.2, goal: 0.1 }
94 changes: 94 additions & 0 deletions ur_simulation_gz/doc/usage.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
Usage
=====

Launch Files
------------

To launch the simulation, two files can be used:

- ``launch/ur_sim_control.launch.py``
- ``launch/ur_sim_moveit.launch.py``

They both start Gazebo, but only the second launches MoveIt! together with it, allowing to plan motions using either MoveGroup interfaces or the Motion Planning panel in Rviz.

So, if only Gazebo and Rviz are needed:

.. code-block:: console

$ ros2 launch ur_simulation_gz ur_sim_control.launch.py ur_type:=ur10e

Which can be tested by using a test script from ``ur_robot_driver`` (if installed), in a new terminal:

.. code-block:: console

$ ros2 launch ur_robot_driver test_joint_trajectory_controller.launch.py

If we also want to be able to use MoveIt!, then:

.. code-block:: console

$ ros2 launch ur_simulation_gz ur_sim_moveit.launch.py ur_type:=ur10e

.. image:: resources/gz_simulation_moveit.png
:width: 95%
:alt: Gazebo with MoveIt!

.. note::

All the additional launch arguments are described in the launch files themselves.

Customization
-------------

Beyond the default usage, the package offers some customization options.

Custom Description
^^^^^^^^^^^^^^^^^^

To use a custom robot / scene description, the launch argument ``description_file`` can be specified, which allows to pass the absolute path of a custom description to both launchers. Together with it, it could be useful to choose a custom Rviz configuration file and the launch argument ``rviz_config_file`` can be passed for that. An example of their usage:

.. code-block:: console

$ ros2 launch ur_simulation_gz ur_sim_control.launch.py ur_type:=ur10e description_file:="/home/ubuntu/ur_gz_test.urdf.xacro" rviz_config_file:="/home/ubuntu/rviz_test.rviz"

tf_prefix
^^^^^^^^^

Also here, like in the driver package, it is possible to specify a tf_prefix using the ``tf_prefix`` launch argument, but for this package this is not the only step required. Since controller loading is handled differently, it is necessary to define a custom controllers file with the desired tf_prefix. Assuming ``tf_prefix:="alice_"``, an example of such file could be:

.. literalinclude:: resources/ur_controllers_test.yaml
:language: yaml
:emphasize-lines: 15-20, 32-37

To load the newly defined file, it is possible to specify its absolute path with the ``controllers_file`` argument. Together with it the desired prefix should be also be specified as argument, like in the following example:

.. code-block:: console

$ ros2 launch ur_simulation_gz ur_sim_control.launch.py ur_type:=ur10e tf_prefix:="alice_" controllers_file:="/home/ubuntu/ur_controllers_test.yaml"

.. note::

The ``tf_prefix`` argument is not available for ``ur_sim_moveit.launch.py``, since it would require a custom definition of the moveit config package for properly setting it up.

Custom World
^^^^^^^^^^^^

The last customization option allows to instantiate the robot in a proper setup instead of an empty world, like the given launch files do by default. The first step to create a complete simulation is to define a world file (.sdf): for this example we can use a simple custom world ``test_world.sdf``, located it in ``ur_gz_simulation/doc/resources``. For more details about building worlds in Gazebo, it's possible to check the `related tutorial <https://gazebosim.org/docs/harmonic/sdf_worlds>`_.
To use the new world changes it's enough to specify its absolute path in the ``world_file`` argument:


.. code-block:: console

$ ros2 launch ur_simulation_gz ur_sim_control.launch.py ur_type:=ur10e world_file:=<path_to_gz_simulation>/doc/resources/test_world.sdf

or using MoveIt!

.. code-block:: console

$ ros2 launch ur_simulation_gz ur_sim_moveit.launch.py ur_type:=ur10e world_file:=<path_to_gz_simulation>/doc/resources/test_world.sdf

In this way, when launching the simulation, Gazebo will use the indicated custom world instead of the default empty, like in the following picture.

.. image:: resources/gz_simulation_custom_world.png
:width: 95%
:alt: Gazebo custom world
Loading