Robot Playground project
========================
The robot playground project contains Python and C++ examples to help you get
started with the Robot Learning Lab. Follow the steps below to install, build,
run and finally submit your first project!
Installation
------------
If you haven't already setup your RLL workspace with the robot playground
project, do so now by following the instructions outlined in the
:doc:`getting_started` guide.
Building and running the project
--------------------------------
Refer to the :doc:`development_workflow` document for detailed information on
how to build and run the project.
As a quick recap, here are the required commands to build and run the project:
.. code-block:: shell
catkin build rll_robot_playground_project
To start the simulation environment run:
.. code-block:: shell
roslaunch rll_robot_playground_project setup_simulation.launch
Run your python code, by executing:
.. code-block:: shell
roslaunch rll_robot_playground_project run_your_code.launch
And to finally submit your code, run:
.. code-block:: shell
roslaunch rll_robot_playground_project submit_project.launch
The project files are located in the
:code:`~/rll_ws/src/rll_robot_playground_project` directory.
.. _robot-playground-example:
Hello World Example
-------------------
To demonstrate how to use all the movement methods described in
:doc:`rll_move_client` we will build a full example that utilizes all of them.
The code is extended step by step as more methods are added.
The examples are snippets of the whole program and each example should run on
its own. For each step, the relevant new lines are highlighted.
.. note::
The example created below is the `hello world` program from the
`Robot Playground Project `_.
It is recommended that you follow along and copy the changes as they are added
into the file :code:`scripts/playground.py` or :code:`src/playground.cpp`, respectively.
This way you can recreate the example for yourself, run the code after every
change and get a better understanding of what is happening.
Hello ROS
^^^^^^^^^
.. tabs::
.. group-tab:: Python
.. literalinclude:: _static/code_examples/hello_world.py
:linenos:
:emphasize-lines: 17,18
:lines: 1-2, 21-36, 184-195
.. group-tab:: C++
.. literalinclude:: _static/code_examples/hello_world.cpp
:language: cpp
:linenos:
:emphasize-lines: 9,10
:lines: 20-29, 191-202
We use the :ref:`move-client-getting-started` template and add some simple
logging output. As the comments indicate, you should use the logging methods
provided by ROS, instead of the system default output.
It's moving!
^^^^^^^^^^^^
The previous example didn't actually move the robot. Lets change that!
.. tabs::
.. group-tab:: Python
.. literalinclude:: _static/code_examples/hello_world.py
:linenos:
:emphasize-lines: 18
:lines: 1-2, 21-34, 38-43, 184-195
.. group-tab:: C++
.. literalinclude:: _static/code_examples/hello_world.cpp
:linenos:
:language: cpp
:emphasize-lines: 10
:lines: 20-27, 31-36, 191-202
We use the :ref:`move_random ` function to move the
robot into a random position. Adding a delay between movements helps to see
the different movements better.
Specifying joint angles
^^^^^^^^^^^^^^^^^^^^^^^
The next example illustrates how to add error checks, which we previously
neglected.
.. tabs::
.. group-tab:: Python
.. literalinclude:: _static/code_examples/hello_world.py
:linenos:
:emphasize-lines: 20, 26, 33-34, 42-43, 45-46
:lines: 1-2, 21-34, 45-76, 184-195
.. group-tab:: C++
.. literalinclude:: _static/code_examples/hello_world.cpp
:linenos:
:language: cpp
:emphasize-lines: 12, 20, 24-27, 34, 36-39
:lines: 20-27, 38-70, 191-202
We use the :ref:`move_joints` function to specify
the seven joint positions. As stated in :ref:`move-client-error-handling`,
service calls return :code:`False` on failure. In this example the second call
:code:`move_client.move_joints(0.0, 0.0, 0.0, pi / 2, 0.0, 0.0, 0.0)` would
move the robot outside the allowed workspace. As a result the call fails and no
movement is made. Without the error check you might not have noticed that
the call failed!
.. hint::
If you check the output log you will notice that the failure has been reported there,
too. Service call failures will always be logged, regardless of your own error checks.
More movement
^^^^^^^^^^^^^
.. tabs::
.. group-tab:: Python
.. literalinclude:: _static/code_examples/hello_world.py
:linenos:
:emphasize-lines: 19-21, 24, 39, 41, 46, 48
:lines: 1-2, 21-34, 78-111, 184-195
.. group-tab:: C++
.. literalinclude:: _static/code_examples/hello_world.cpp
:linenos:
:language: cpp
:emphasize-lines: 13-17, 20, 36, 40, 45, 47
:lines: 20-27, 48, 71-110, 191-202
Point based movement ist easier to understand. You only need to specify
the position and orientation of the end effector and the robot will move there.
However, you cannot control how the robot gets to this position.
The orientation part of a pose is stored as a quaternion. You usually don't set
the quaternion manually. Use the provided helper functions to generate the
quaternion for you.
Linear movement
^^^^^^^^^^^^^^^
.. tabs::
.. group-tab:: Python
.. literalinclude:: _static/code_examples/hello_world.py
:linenos:
:emphasize-lines: 23, 26, 29, 32, 36, 39, 41, 44-45, 47
:lines: 1-2, 21-34, 80, 118-153, 184-195
.. group-tab:: C++
.. literalinclude:: _static/code_examples/hello_world.cpp
:linenos:
:language: cpp
:emphasize-lines: 15, 18-20, 23, 26, 30, 33, 36, 39, 40, 43
:lines: 20-27, 74, 116-149, 191-202
Previously we moved in a point to point fashion to a desired pose.
However, this has the drawback that we cannot guarantee how the end effector
is reaching its new position. One alternative is to use
:ref:`move-client-move-lin` instead. This ensures that the end effector is
moved on a linear trajectory to its target position. In the example above,
three consecutive linear movements, forming a triangular path, are executed.
.. tabs::
.. group-tab:: Python
.. literalinclude:: _static/code_examples/hello_world.py
:linenos:
:emphasize-lines: 26, 33, 28, 35
:lines: 1-2, 21-34, 80, 100, 126, 148-166, 184-195
.. group-tab:: C++
.. literalinclude:: _static/code_examples/hello_world.cpp
:linenos:
:language: cpp
:emphasize-lines: 22, 31, 24, 33
:lines: 20-27, 48, 74, 97, 124-126, 150-171, 191-202
Since :code:`move_lin()` requires the end effector to travel on a
linear trajectory, it is more constrained than :code:`move_ptp()`
which imposes no restrictions on how to reach the goal pose.
It is therefore possible that :code:`move_lin()` fails where a movement with
:code:`move_ptp()` succeeds, as illustrated in the example above.
.. _robot-playground-complete:
Complete example
^^^^^^^^^^^^^^^^
The complete code, which encompasses the examples above, is shown below:
.. tabs::
.. group-tab:: Python
.. literalinclude:: _static/code_examples/hello_world.py
:linenos:
:caption: Complete hello_world.py example
:lines: 1-2, 21-
.. group-tab:: C++
.. literalinclude:: _static/code_examples/hello_world.cpp
:linenos:
:language: cpp
:caption: Complete hello_world.cpp example
:lines: 20-