Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions .github/helpers/check_urls.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ urls=$(grep -oP '(http|ftp|https):\/\/([a-zA-Z0-9_-]+(?:(?:\.[a-zA-Z0-9_-]+)+))(
fail_counter=0

FAILED_LINKS=()
CHECKED_LINKS=()
for item in $urls; do
# echo $item
skip=0
Expand All @@ -53,15 +54,18 @@ for item in $urls; do
filename=$(echo "$item" | cut -d':' -f1)
url=$(echo "$item" | cut -d':' -f2-)
echo -n "Checking $url from file $filename"
if ! curl --head --silent --fail "$url" 2>&1 > /dev/null; then
echo -e " \033[0;31mNOT FOUND\033[32m\n"
if [[ $(echo ${CHECKED_LINKS[@]} | fgrep -w $url) ]]; then
echo -e " \033[36malready checked\033[0m"
elif ! curl --head --silent --fail "$url" 2>&1 > /dev/null; then
echo -e " \033[0;31mNOT FOUND\033[0m"
FAILED_LINKS+=("$url from file $filename")
((fail_counter=fail_counter+1))
else
printf " \033[32mok\033[0m\n"
echo -e " \033[32mok\033[0m"
fi
CHECKED_LINKS+=("$url")
done

echo "Failed files:"
printf '%s\n' "${FAILED_LINKS[@]}"
exit $fail_counter
exit $fail_counter
12 changes: 3 additions & 9 deletions doc/architecture/instruction_executor.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.. _instruction_executor:

Instruction Executor
====================

Expand All @@ -21,12 +23,4 @@ for sending motion instructions to the robot. Hence, it requires a :ref:`ur_driv
Therefore, all parameters and restrictions of these functions apply. For example, velocity and
acceleration parameters will be ignored if there is a time > 0 given.

As a minimal working example, please see ``examples/instruction_executor.cpp`` example:

.. literalinclude:: ../../examples/instruction_executor.cpp
:language: c++
:caption: examples/instruction_executor.cpp
:linenos:
:lineno-match:
:start-at: g_my_driver.reset
:end-at: g_my_driver->stopControl();
As a minimal working example, please see the :ref:`instruction_executor_example`.
10 changes: 1 addition & 9 deletions doc/architecture/script_sender.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,7 @@ corresponding request when starting a program on the robot that contains the **E
program node. In order to work properly, make sure that the IP address and script sender port are
configured correctly on the robot.

The following example creates a ``ScriptSender`` listening on port ``12345`` and sends the script
``textmsg("Hello, World!")`` when requested. A fully compilable example can be found in `script_sender.cpp <https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/examples/script_sender.cpp>`_

.. literalinclude:: ../../examples/script_sender.cpp
:language: c++
:caption: examples/script_sender.cpp
:linenos:
:lineno-match:
:start-at: constexpr uint32_t PORT
An example of how to use the ``ScriptSender`` class can be found in the :ref:`script_sender_example`.

.. note::
PolyScope X users cannot use the URCap linked above. There is a development version of a URCapX
Expand Down
12 changes: 0 additions & 12 deletions doc/example.rst

This file was deleted.

28 changes: 28 additions & 0 deletions doc/examples.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
Usage examples
==============

This library contains a number of examples how this library can be used. You can use them as a
starting point for your own applications.

All examples take a robot's IP address as a first argument and some of them take a maximum run
duration (in seconds) as second argument. If the second argument is omitted, some of the examples
may be running forever until manually stopped.

.. note:: Most of these examples use the driver's headless mode. Therefore, on an e-Series (PolyScope 5) robot, the robot has to be
in *remote control mode* to work.

.. toctree::
:maxdepth: 1

examples/dashboard_client
examples/force_mode
examples/freedrive
examples/instruction_executor
examples/primary_pipeline
examples/primary_pipeline_calibration
examples/rtde_client
examples/script_sender
examples/spline_example
examples/tool_contact_example
examples/trajectory_point_interface
examples/ur_driver
82 changes: 82 additions & 0 deletions doc/examples/dashboard_client.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
:github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/examples/dashboard_client.rst

Dashboard client example
========================

This example shows how to use the builtin `Dashboard server <https://www.universal-robots.com/articles/ur-articles/dashboard-server-e-series-port-29999/>`_ to communicate with a robot.

.. note::

The Dashboard Server is only available on CB3 and e-Series robots. It is not available on
PolyScope X.


The `dashboard_example.cpp <https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/examples/dashboard_example.cpp>`_ shows how to use this class:

.. note:: For the following example to work on an e-Series (PolyScope 5) robot, the robot has to be
in *remote control mode*.

.. literalinclude:: ../../examples/dashboard_example.cpp
:language: c++
:caption: examples/dashboard_example.cpp
:linenos:
:lineno-match:
:start-at: std::make_unique<DashboardClient>
:end-at: my_dashboard->commandCloseSafetyPopup();

At first, a ``DashboardClient`` object is created with the IP address of the robot. Then, the
client is connected to the robot. After that, the client sends a command to the robot and receives
the answer.

Some commands support getting the response from the robot. For example, the
``commandPolyScopeVersion()`` function:

.. literalinclude:: ../../examples/dashboard_example.cpp
:language: c++
:caption: examples/dashboard_example.cpp
:linenos:
:lineno-match:
:start-at: // Get the PolyScope version
:end-at: URCL_LOG_INFO(version.c_str());


The ``DashboardClient`` can easily be used to cycle through the robot's states, for example for
initialization:

.. literalinclude:: ../../examples/dashboard_example.cpp
:language: c++
:caption: examples/dashboard_example.cpp
:linenos:
:lineno-match:
:start-at: // Power it on
:end-at: // Load existing program

All commands are blocking and will wait for the necessary action being done. The dashboard server's
response will be compared with an expected response. For example, when calling
``commandPowerOn(timeout)``, it is checked that the dashboard server is answering ``"Powering on"`` and
then it is queried until the robot reports ``"Robotmode: IDLE"`` or until the timeout is reached.
The example contains more commands that follow the same scheme.


If you want to send a query / command to the dashboard server and only want to receive the
response, you can use the ``sendAndReceive()`` function:

.. literalinclude:: ../../examples/dashboard_example.cpp
:language: c++
:caption: examples/dashboard_example.cpp
:linenos:
:lineno-match:
:start-at: // Make a raw request and save the response
:end-at: URCL_LOG_INFO("Program state: %s", program_state.c_str());

For checking the response against an expected regular expression use ``sendRequest()``:

.. literalinclude:: ../../examples/dashboard_example.cpp
:language: c++
:caption: examples/dashboard_example.cpp
:linenos:
:lineno-match:
:start-at: // The response can be checked with a regular expression
:end-at: URCL_LOG_INFO("Power off command success: %d", success);


63 changes: 63 additions & 0 deletions doc/examples/force_mode.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
:github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/examples/force_mode.rst

Force Mode example
==================

The ``ur_client_library`` supports leveraging the robot's force mode directly. An example on how to
use it can be found in `force_mode_example.cpp <https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/examples/force_mode_example.cpp>`_.

In order to utilize force mode, we'll have to create and initialize a full ``UrDriver`` object
first:

.. literalinclude:: ../../examples/force_mode_example.cpp
:language: c++
:caption: examples/force_mode_example.cpp
:linenos:
:lineno-match:
:start-at: // Now the robot is ready to receive a program
:end-at: // End of initialization

Start force mode
----------------

After that, we can start force mode by calling the ``startForceMode()`` function:

.. literalinclude:: ../../examples/force_mode_example.cpp
:language: c++
:caption: examples/force_mode_example.cpp
:linenos:
:lineno-match:
:start-at: // Start force mode
:end-at: if (!success)

All parameters for the force mode are included into the ``startForceMode()`` function call. If you
want to change the parameters, e.g. change the forces applied, you can simply call
``startForceMode()`` again with the new parameters.

.. note::
CB3 robots don't support specifying force_mode's ``gain_scaling``, so there are two different
functions available.

Once force mode is started successfully, we'll have to send keepalive messages to the robot in
order to keep the communication active:

.. literalinclude:: ../../examples/force_mode_example.cpp
:language: c++
:caption: examples/force_mode_example.cpp
:linenos:
:lineno-match:
:start-at: std::chrono::duration<double> time_done(0);
:end-at: URCL_LOG_INFO("Timeout reached.");

Stop force mode
---------------

Once finished, force_mode can be stopped by calling ``endForceMode()``.

.. literalinclude:: ../../examples/force_mode_example.cpp
:language: c++
:caption: examples/force_mode_example.cpp
:linenos:
:lineno-match:
:start-at: endForceMode()
:end-at: endForceMode()
70 changes: 70 additions & 0 deletions doc/examples/freedrive.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
:github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/examples/freedrive.rst

Freedrive Mode example
======================

`Freedrive
<https://www.universal-robots.com/manuals/EN/HTML/SW5_20/Content/prod-scriptmanual/G5/freedrive_mode.htm>`_
allows the robot arm to be manually pulled into desired positions and/or poses. The joints move
with little resistance because the brakes are released.

An example to utilize the freedrive mode can be found in the `freedrive_example.cpp <https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/examples/freedrive_example.cpp>`_.

.. note:: For the following example to work on an e-Series (PolyScope 5) robot, the robot has to be
in *remote control mode*.

At first, we create a ``ExampleRobotWrapper`` object in order to initialize communication with the
robot.

.. literalinclude:: ../../examples/freedrive_example.cpp
:language: c++
:caption: examples/freedrive_example.cpp
:linenos:
:lineno-match:
:start-at: bool headless_mode = true;
:end-before: URCL_LOG_INFO("Starting freedrive mode");


Start freedrive mode
--------------------

The ``UrDriver`` provides a method to start freedrive mode directly:

.. literalinclude:: ../../examples/freedrive_example.cpp
:language: c++
:caption: examples/freedrive_example.cpp
:linenos:
:lineno-match:
:start-at: URCL_LOG_INFO("Starting freedrive mode");
:end-at: sendFreedriveMessageOrDie(control::FreedriveControlMessage::FREEDRIVE_START);

As it is potentially dangerous to leave the robot in freedrive mode, the robot program expect
frequent keepalive messages to verify that the remote connection is still available and freedrive
mode is being expected to be active.

Freedrive mode will be active from this point on until it is either stopped, or no keepalive
message is received by the robot anymore.

Therefore, we have to make sure to send regular keepalive messages to the robot. The following
section will keep freedrive mode active for a period of time defined in ``seconds_to_run``.

.. literalinclude:: ../../examples/freedrive_example.cpp
:language: c++
:caption: examples/freedrive_example.cpp
:linenos:
:lineno-match:
:start-at: std::chrono::duration<double> time_done(0);
:end-before: sendFreedriveMessageOrDie(control::FreedriveControlMessage::FREEDRIVE_STOP);

Stop force Mode
---------------

To stop force mode either stop sending keepalive signals or request deactivating it explicitly:

.. literalinclude:: ../../examples/freedrive_example.cpp
:language: c++
:caption: examples/freedrive_example.cpp
:linenos:
:lineno-match:
:start-at: sendFreedriveMessageOrDie(control::FreedriveControlMessage::FREEDRIVE_STOP);
:end-at: sendFreedriveMessageOrDie(control::FreedriveControlMessage::FREEDRIVE_STOP);
66 changes: 66 additions & 0 deletions doc/examples/instruction_executor.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
:github_url: https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/doc/examples/instruction_executor.rst

.. _instruction_executor_example:

Instruction Executor example
============================

This example shows how to use the :ref:`instruction_executor` class. It can be used for easily
executing a sequence of instructions such as motions on the robot using the built-in URScript functions.

The `instruction_executor.cpp <https://github.com/UniversalRobots/Universal_Robots_Client_Library/blob/master/examples/instruction_executor.cpp>`_ shows how to use this class:

.. note:: For the instruciton executor to work there has to be an established connection to the
:ref:`reverse_interface`. That means, the respective program has to be running on the robot. The
example below will do that automatically, if the connected robot is in *remote_control* mode.


.. literalinclude:: ../../examples/instruction_executor.cpp
:language: c++
:caption: examples/instruction_executor.cpp
:linenos:
:lineno-match:
:start-at: std::unique_ptr<urcl::ToolCommSetup> tool_comm_setup;
:end-at: auto instruction_executor = std::make_shared<urcl::InstructionExecutor>(g_my_driver);

At first, a ``InstructionExecutor`` object is created with the URDriver object as it needs that
for communication with the robot.

Currently, the ``InstructionExecutor`` can either be used to run sequences of motions or single motions.

Execute a sequence of motions
-----------------------------

To run a sequence of motions, create an
``std::vector<std::shared_ptr<urcl::cointrol::MotionPrimitive>>`` and pass it to the
``executeMotion`` function:

.. literalinclude:: ../../examples/instruction_executor.cpp
:language: c++
:caption: examples/instruction_executor.cpp
:linenos:
:lineno-match:
:start-at: // Trajectory definition
:end-at: instruction_executor->executeMotion(motion_sequence);

Each element in the motion sequence can be a different motion type. In the example, there are two
``MoveJ`` motions and two ``MoveL`` motion. The primitives' parameters are directly forwarded to
the underlying script functions, so the parameter descriptions for them apply, as well.
Particularly, you may want to choose between either a time-based execution speed or an acceleration
/ velocity parametrization. The latter will be ignored if a time > 0 is given.

Execute a single motion
-----------------------

To run a single motion, the ``InstructionExecutor`` provides the methods ``moveJ(...)`` and
``moveL(...)``:

.. literalinclude:: ../../examples/instruction_executor.cpp
:language: c++
:caption: examples/instruction_executor.cpp
:linenos:
:lineno-match:
:start-at: double goal_time_sec = 2.0;
:end-before: g_my_driver->stopControl();

Again, time parametrization has priority over acceleration / velocity parameters.
Loading
Loading