Skip to content

Commit

Permalink
Added rosdoc sphinx documentation
Browse files Browse the repository at this point in the history
With this we can improve our documentation experience by a hosted rendered documentation
on docs.ros.org.
  • Loading branch information
fmauch authored and VinDp committed Jun 17, 2024
1 parent dc6fd88 commit 22d966a
Show file tree
Hide file tree
Showing 15 changed files with 791 additions and 474 deletions.
189 changes: 2 additions & 187 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,11 @@
# Universal Robots Client Library
* [Universal Robots Client Library](#universal-robots-client-library)
* [Requirements](#requirements)
* [Build instructions](#build-instructions)
* [Plain cmake](#plain-cmake)
* [Inside a ROS workspace](#inside-a-ros-workspace)
* [Use this library in other projects](#use-this-library-in-other-projects)
* [License](#license)
* [Library contents](#library-contents)
* [Example driver](#example-driver)
* [Architecture](#architecture)
* [RTDEClient](#rtdeclient)
* [RTDEWriter](#rtdewriter)
* [ReverseInterface](#reverseinterface)
* [ScriptSender](#scriptsender)
* [Other public interface functions](#other-public-interface-functions)
* [check_calibration()](#check_calibration)
* [sendScript()](#sendscript)
* [DashboardClient](#dashboardclient)
* [A word on the primary / secondary interface](#a-word-on-the-primary--secondary-interface)
* [A word on Real-Time scheduling](#a-word-on-real-time-scheduling)
* [Producer / Consumer architecture](#producer--consumer-architecture)
Expand Down Expand Up @@ -54,67 +43,7 @@ robotic manipulators.


## Build instructions
### Plain cmake
To build this library standalone so that you can build you own applications using this library,
follow the usual cmake procedure:
```bash
cd <clone of this repository>
mkdir build && cd build
cmake ..
make
sudo make install
```

This will install the library into your system so that it can be used by other cmake projects
directly.

### Inside a ROS workspace
If you want to build this library inside a ROS workspace, e.g. because you want to build the
[Universal Robots ROS driver](https://github.com/UniversalRobots/Universal_Robots_ROS_Driver) from
source, you cannot use `catkin_make` directly, as this library is not a catkin package. Instead, you
will have to use
[`catkin_make_isolated`](http://docs.ros.org/independent/api/rep/html/rep-0134.html) or [catkin
build](https://catkin-tools.readthedocs.io/en/latest/verbs/catkin_build.html) to build your
workspace.

## Use this library in other projects
When you want to use this library in other cmake projects, make sure to
* Add `find_package(ur_client_library REQUIRED)` to your `CMakeLists.txt`
* add `ur_client_library::urcl` to the list of `target_link_libraries(...)` commands inside your
CMakeLists.txt file

As a minimal example, take the following "project":
```c++
/*main.cpp*/

#include <iostream>
#include <ur_client_library/ur/dashboard_client.h>

int main(int argc, char* argv[])
{
urcl::DashboardClient my_client("192.168.56.101");
bool connected = my_client.connect();
if (connected)
{
std::string answer = my_client.sendAndReceive("PolyscopeVersion\n");
std::cout << answer << std::endl;
my_client.disconnect();
}
return 0;
}

```
```cmake
# CMakeLists.txt
cmake_minimum_required(VERSION 3.0.2)
project(minimal_example)
find_package(ur_client_library REQUIRED)
add_executable(db_client main.cpp)
target_link_libraries(db_client ur_client_library::urcl)
```
See [Build / installation](docs/installation.rst)

## License
The majority of this library is licensed under the Apache-2.0 licensed. However, certain parts are
Expand Down Expand Up @@ -155,121 +84,7 @@ sure to
simplicity reasons it doesn't use any sophisticated method to locate the required files.

## Architecture
The image below shows a rough architecture overview that should help developers to use the different
modules present in this library. Note that this is an incomplete view on the classes involved.

[![Data flow](doc/dataflow.svg "Data flow")](doc/dataflow.svg)

The core of this library is the `UrDriver` class which creates a
fully functioning robot interface. For details on how to use it, please see the [Example
driver](#example-driver) section.

The `UrDriver`'s modules will be explained in the following.

### RTDEClient
The `RTDEClient` class serves as a standalone
[RTDE](https://www.universal-robots.com/articles/ur-articles/real-time-data-exchange-rtde-guide/)
client. To use the RTDE-Client, you'll have to initialize and start it separately:

```c++
rtde_interface::RTDEClient my_client(ROBOT_IP, notifier, OUTPUT_RECIPE, INPUT_RECIPE);
my_client.init();
my_client.start();
while (true)
{
std::unique_ptr<rtde_interface::DataPackage> data_pkg = my_client.getDataPackage(READ_TIMEOUT);
if (data_pkg)
{
std::cout << data_pkg->toString() << std::endl;
}
}
```
Upon construction, two recipe files have to be given, one for the RTDE inputs, one for the RTDE
outputs. Please refer to the [RTDE
guide](https://www.universal-robots.com/articles/ur-articles/real-time-data-exchange-rtde-guide/)
on which elements are available.
Inside the `RTDEclient` data is received in a separate thread, parsed by the `RTDEParser` and added
to a pipeline queue.
Right after calling `my_client.start()`, it should be made sure to read the buffer from the
`RTDEClient` by calling `getDataPackage()` frequently. The Client's queue can only contain 1 item
at a time, so a `Pipeline producer overflowed!` error will be raised if the buffer isn't read before
the next package arrives.
For writing data to the RTDE interface, use the `RTDEWriter` member of the `RTDEClient`. It can be
retrieved by calling `getWriter()` method. The `RTDEWriter` provides convenience methods to write
all data available at the RTDE interface. Make sure that the required keys are configured inside the
input recipe, as otherwise the send-methods will return `false` if the data field is not setup in
the recipe.
An example of a standalone RTDE-client can be found in the `examples` subfolder. To run it make
sure to
* have an instance of a robot controller / URSim running at the configured IP address (or adapt the
address to your needs)
* run it from the package's main folder (the one where this README.md file is stored), as for
simplicity reasons it doesn't use any sophisticated method to locate the required files.
#### RTDEWriter
The `RTDEWriter` class provides an interface to write data to the RTDE interface. Data fields that
should be written have to be defined inside the `INPUT_RECIPE` as noted above.
The class offers specific methods for every RTDE input possible to write.
Data is sent asynchronously to the RTDE interface.
### ReverseInterface
The `ReverseInterface` opens a TCP port on which a custom protocol is implemented between the
robot and the control PC. The port can be specified in the class constructor.
It's basic functionality is to send a vector of floating point data together with a mode. It is
meant to send joint positions or velocities together with a mode that tells the robot how to
interpret those values (e.g. `SERVOJ`, `SPEEDJ`). Therefore, this interface can be used to do motion
command streaming to the robot.
In order to use this class in an application together with a robot, make sure that a corresponding
URScript is running on the robot that can interpret the commands sent. See [this example
script](resources/external_control.urscript) for reference.
Also see the [ScriptSender](#scriptsender) for a way to define the corresponding URScript on the
control PC and sending it to the robot upon request.
### ScriptSender
The `ScriptSender` class opens a tcp socket on the remote PC whose single purpose it is to answer
with a URScript code snippet on a "*request_program*" request. The script code itself has to be
given to the class constructor.
Use this class in conjunction with the [**External Control**
URCap](https://github.com/UniversalRobots/Universal_Robots_ExternalControl_URCap) which will make
the corresponding request when starting a program on the robot that contains the **External
Control** program node. In order to work properly, make sure that the IP address and script sender
port are configured correctly on the robot.
### Other public interface functions
This section shall explain the public interface functions that haven't been covered above
#### `check_calibration()`
This function opens a connection to the primary interface where it will receive a calibration
information as the first message. The checksum from this calibration info is compared to the one
given to this function. Connection to the primary interface is dropped afterwards.
#### `sendScript()`
This function sends given URScript code directly to the secondary interface. The
`sendRobotProgram()` function is a special case that will send the script code given in the
`RTDEClient` constructor.
### DashboardClient
The `DashboardClient` wraps the calls on the [Dashboard server](https://www.universal-robots.com/articles/ur-articles/dashboard-server-e-series-port-29999/) directly into C++ functions.
After connecting to the dashboard server by using the `connect()` function, dashboard calls can be
sent using the `sendAndReceive()` function. Answers from the dashboard server will be returned as
string from this function. If no answer is received, a `UrException` is thrown.
Note: In order to make this more useful developers are expected to wrap this bare interface into
something that checks the returned string for something that is expected. See the
[DashboardClientROS](https://github.com/UniversalRobots/Universal_Robots_ROS_Driver/blob/master/ur_robot_driver/include/ur_robot_driver/dashboard_client_ros.h) as an example.
See [Architecture documentation](docs/architecture.rst)

## A word on the primary / secondary interface
Currently, this library doesn't support the primary interface very well, as the [Universal Robots
Expand Down
Empty file added doc/.static
Empty file.
Empty file added doc/.templates
Empty file.
142 changes: 142 additions & 0 deletions doc/architecture.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
Library architecture
====================

The image below shows a rough architecture overview that should help developers to use the different
modules present in this library. Note that this is an incomplete view on the classes involved.

.. image:: images/dataflow.svg
:width: 100%
:alt: Data flow


The core of this library is the ``UrDriver`` class which creates a
fully functioning robot interface. For details on how to use it, please see the [Example
driver](#example-driver) section.

The ``UrDriver``'s modules will be explained in the following.

RTDEClient
----------

The ``RTDEClient`` class serves as a standalone
`RTDE <https://www.universal-robots.com/articles/ur-articles/real-time-data-exchange-rtde-guide/>`_
client. To use the RTDE-Client, you'll have to initialize and start it separately:

.. code-block:: c++

rtde_interface::RTDEClient my_client(ROBOT_IP, notifier, OUTPUT_RECIPE, INPUT_RECIPE);
my_client.init();
my_client.start();
while (true)
{
std::unique_ptr<rtde_interface::DataPackage> data_pkg = my_client.getDataPackage(READ_TIMEOUT);
if (data_pkg)
{
std::cout << data_pkg->toString() << std::endl;
}
}

Upon construction, two recipe files have to be given, one for the RTDE inputs, one for the RTDE
outputs. Please refer to the `RTDE
guide <https://www.universal-robots.com/articles/ur-articles/real-time-data-exchange-rtde-guide/>`_
on which elements are available.

Inside the ``RTDEclient`` data is received in a separate thread, parsed by the ``RTDEParser`` and
added to a pipeline queue.

Right after calling ``my_client.start()``, it should be made sure to read the buffer from the
``RTDEClient`` by calling ``getDataPackage()`` frequently. The Client's queue can only contain 1
item at a time, so a ``Pipeline producer overflowed!`` error will be raised if the buffer isn't read
before the next package arrives.

For writing data to the RTDE interface, use the ``RTDEWriter`` member of the ``RTDEClient``. It can be
retrieved by calling ``getWriter()`` method. The ``RTDEWriter`` provides convenience methods to write
all data available at the RTDE interface. Make sure that the required keys are configured inside the
input recipe, as otherwise the send-methods will return ``false`` if the data field is not setup in
the recipe.

An example of a standalone RTDE-client can be found in the ``examples`` subfolder. To run it make
sure to

* have an instance of a robot controller / URSim running at the configured IP address (or adapt the
address to your needs)
* run it from the package's main folder, as for simplicity reasons it doesn't use any sophisticated
method to locate the required files.


RTDEWriter
^^^^^^^^^^

The ``RTDEWriter`` class provides an interface to write data to the RTDE interface. Data fields that
should be written have to be defined inside the ``INPUT_RECIPE`` as noted above.

The class offers specific methods for every RTDE input possible to write.

Data is sent asynchronously to the RTDE interface.

ReverseInterface
----------------

The ``ReverseInterface`` opens a TCP port on which a custom protocol is implemented between the
robot and the control PC. The port can be specified in the class constructor.

It's basic functionality is to send a vector of floating point data together with a mode. It is
meant to send joint positions or velocities together with a mode that tells the robot how to
interpret those values (e.g. ``SERVOJ``, ``SPEEDJ``). Therefore, this interface can be used to do
motion command streaming to the robot.

In order to use this class in an application together with a robot, make sure that a corresponding
URScript is running on the robot that can interpret the commands sent. See `this example
script <../resources/external_control.urscript>`_ for reference.

Also see the :ref:`ScriptSender` for a way to define the corresponding URScript on the
control PC and sending it to the robot upon request.

.. _ScriptSender:

ScriptSender
------------

The ``ScriptSender`` class opens a tcp socket on the remote PC whose single purpose it is to answer
with a URScript code snippet on a "*request_program*" request. The script code itself has to be
given to the class constructor.

Use this class in conjunction with the `External Control URCap
<https://github.com/UniversalRobots/Universal_Robots_ExternalControl_URCap>`_ which will make the
corresponding request when starting a program on the robot that contains the **External Control**
program node. In order to work properly, make sure that the IP address and script sender port are
configured correctly on the robot.

Other public interface functions
--------------------------------

This section shall explain the public interface functions that haven't been covered above


check_calibration()
^^^^^^^^^^^^^^^^^^^

This function opens a connection to the primary interface where it will receive a calibration
information as the first message. The checksum from this calibration info is compared to the one
given to this function. Connection to the primary interface is dropped afterwards.

sendScript()
^^^^^^^^^^^^

This function sends given URScript code directly to the secondary interface. The
``sendRobotProgram()`` function is a special case that will send the script code given in the
``RTDEClient`` constructor.

DashboardClient
---------------

The ``DashboardClient`` wraps the calls on the `Dashboard server <https://www.universal-robots.com/articles/ur-articles/dashboard-server-e-series-port-29999/>`_
directly into C++ functions.

After connecting to the dashboard server by using the ``connect()`` function, dashboard calls can be
sent using the ``sendAndReceive()`` function. Answers from the dashboard server will be returned as
string from this function. If no answer is received, a ``UrException`` is thrown.

Note: In order to make this more useful developers are expected to wrap this bare interface into
something that checks the returned string for something that is expected. See the
`DashboardClientROS <https://github.com/UniversalRobots/Universal_Robots_ROS_Driver/blob/master/ur_robot_driver/include/ur_robot_driver/dashboard_client_ros.h>`_ as an example.
Loading

0 comments on commit 22d966a

Please sign in to comment.