Skip to content

Commit b4fb90b

Browse files
committed
Rebase from 'upstream'
1 parent e36262b commit b4fb90b

27 files changed

+1687
-638
lines changed

.github/helpers/check_urls.sh

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,21 @@ urls=$(grep -oP "(http|ftp|https):\/\/([a-zA-Z0-9_-]+(?:(?:\.[a-zA-Z0-9_-]+)+))(
77

88
fail_counter=0
99

10+
FAILED_LINKS=()
1011
for item in $urls; do
1112
# echo $item
1213
filename=$(echo "$item" | cut -d':' -f1)
1314
url=$(echo "$item" | cut -d':' -f2-)
14-
echo "Checking $url from file $filename"
15+
echo -n "Checking $url from file $filename"
1516
if ! curl --head --silent --fail "$url" 2>&1 > /dev/null; then
16-
echo "Invalid link in file $filename: $url"
17+
echo -e " \033[0;31mNOT FOUND\033[32m\n"
18+
FAILED_LINKS+=("$url from file $filename")
1719
((fail_counter=fail_counter+1))
1820
else
19-
echo "$url ok"
21+
printf " \033[32mok\033[0m\n"
2022
fi
2123
done
2224

25+
echo "Failed files:"
26+
printf '%s\n' "${FAILED_LINKS[@]}"
2327
exit $fail_counter

.github/workflows/ci.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ jobs:
100100
--exclude-dir=CMakeModules \
101101
--exclude=tcp_socket.cpp \
102102
--exclude-dir=debian \
103-
--exclude=real_time.md \
104103
--exclude=dataflow.graphml \
105104
--exclude=start_ursim.sh
106105

.markdownlint.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
MD013:
3+
line_length: 100
4+
MD033:
5+
allowed_elements: [img, a]

.pre-commit-config.yaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,13 @@ repos:
22
- repo: https://github.com/pre-commit/mirrors-clang-format
33
rev: 'v14.0.6'
44
hooks:
5-
- id: clang-format
5+
- id: clang-format
6+
- repo: https://github.com/DavidAnson/markdownlint-cli2
7+
rev: v0.13.0
8+
hooks:
9+
- id: markdownlint-cli2
10+
exclude: "include/ur_client_library/queue/LICENSE.md"
11+
- repo: https://github.com/sphinx-contrib/sphinx-lint
12+
rev: v0.9.1
13+
hooks:
14+
- id: sphinx-lint

CHANGELOG.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22
Changelog for package ur_client_library
33
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
44

5+
1.4.0 (2024-09-10)
6+
------------------
7+
* Ensure that the targets are reachable within the robots limits (`#184 <https://github.com/UniversalRobots/Universal_Robots_Client_Library/issues/184>`_)
8+
* Analog domain (`#211 <https://github.com/UniversalRobots/Universal_Robots_Client_Library/issues/211>`_)
9+
* Fix clang compilation error (`#210 <https://github.com/UniversalRobots/Universal_Robots_Client_Library/issues/210>`_)
10+
* Moved reset of speed slider to correct teardown function, so that it … (`#206 <https://github.com/UniversalRobots/Universal_Robots_Client_Library/issues/206>`_)
11+
…resets between each test.
12+
* [doc] Fix syntax in example.rst (`#207 <https://github.com/UniversalRobots/Universal_Robots_Client_Library/issues/207>`_)
13+
* [doc] Migrate documentation to sphinx (`#95 <https://github.com/UniversalRobots/Universal_Robots_Client_Library/issues/95>`_)
14+
* Contributors: Felix Exner, Mads Holm Peters, Remi Siffert, URJala
15+
516
1.3.7 (2024-06-03)
617
------------------
718
* [ci] Update CI

README.md

Lines changed: 70 additions & 252 deletions
Large diffs are not rendered by default.

doc/architecture.rst

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
Library architecture
2+
====================
3+
4+
The image below shows a rough architecture overview that should help developers to use the different
5+
modules present in this library. Note that this is an incomplete view on the classes involved.
6+
7+
.. image:: images/dataflow.svg
8+
:width: 100%
9+
:alt: Data flow
10+
11+
12+
The core of this library is the ``UrDriver`` class which creates a
13+
fully functioning robot interface. For details on how to use it, please see the
14+
:ref:`example-driver` section.
15+
16+
The ``UrDriver``'s modules will be explained in the following.
17+
18+
RTDEClient
19+
----------
20+
21+
The ``RTDEClient`` class serves as a standalone
22+
`RTDE <https://www.universal-robots.com/articles/ur-articles/real-time-data-exchange-rtde-guide/>`_
23+
client. To use the RTDE-Client, you'll have to initialize and start it separately:
24+
25+
.. code-block:: c++
26+
27+
rtde_interface::RTDEClient my_client(ROBOT_IP, notifier, OUTPUT_RECIPE, INPUT_RECIPE);
28+
my_client.init();
29+
my_client.start();
30+
while (true)
31+
{
32+
std::unique_ptr<rtde_interface::DataPackage> data_pkg = my_client.getDataPackage(READ_TIMEOUT);
33+
if (data_pkg)
34+
{
35+
std::cout << data_pkg->toString() << std::endl;
36+
}
37+
}
38+
39+
Upon construction, two recipe files have to be given, one for the RTDE inputs, one for the RTDE
40+
outputs. Please refer to the `RTDE
41+
guide <https://www.universal-robots.com/articles/ur-articles/real-time-data-exchange-rtde-guide/>`_
42+
on which elements are available.
43+
44+
Inside the ``RTDEclient`` data is received in a separate thread, parsed by the ``RTDEParser`` and
45+
added to a pipeline queue.
46+
47+
Right after calling ``my_client.start()``, it should be made sure to read the buffer from the
48+
``RTDEClient`` by calling ``getDataPackage()`` frequently. The Client's queue can only contain 1
49+
item at a time, so a ``Pipeline producer overflowed!`` error will be raised if the buffer isn't read
50+
before the next package arrives.
51+
52+
For writing data to the RTDE interface, use the ``RTDEWriter`` member of the ``RTDEClient``. It can be
53+
retrieved by calling ``getWriter()`` method. The ``RTDEWriter`` provides convenience methods to write
54+
all data available at the RTDE interface. Make sure that the required keys are configured inside the
55+
input recipe, as otherwise the send-methods will return ``false`` if the data field is not setup in
56+
the recipe.
57+
58+
An example of a standalone RTDE-client can be found in the ``examples`` subfolder. To run it make
59+
sure to
60+
61+
* have an instance of a robot controller / URSim running at the configured IP address (or adapt the
62+
address to your needs)
63+
* run it from the package's main folder, as for simplicity reasons it doesn't use any sophisticated
64+
method to locate the required files.
65+
66+
67+
RTDEWriter
68+
^^^^^^^^^^
69+
70+
The ``RTDEWriter`` class provides an interface to write data to the RTDE interface. Data fields that
71+
should be written have to be defined inside the ``INPUT_RECIPE`` as noted above.
72+
73+
The class offers specific methods for every RTDE input possible to write.
74+
75+
Data is sent asynchronously to the RTDE interface.
76+
77+
ReverseInterface
78+
----------------
79+
80+
The ``ReverseInterface`` opens a TCP port on which a custom protocol is implemented between the
81+
robot and the control PC. The port can be specified in the class constructor.
82+
83+
It's basic functionality is to send a vector of floating point data together with a mode. It is
84+
meant to send joint positions or velocities together with a mode that tells the robot how to
85+
interpret those values (e.g. ``SERVOJ``, ``SPEEDJ``). Therefore, this interface can be used to do
86+
motion command streaming to the robot.
87+
88+
In order to use this class in an application together with a robot, make sure that a corresponding
89+
URScript is running on the robot that can interpret the commands sent. See `this example
90+
script <../resources/external_control.urscript>`_ for reference.
91+
92+
Also see the :ref:`ScriptSender` for a way to define the corresponding URScript on the
93+
control PC and sending it to the robot upon request.
94+
95+
.. _ScriptSender:
96+
97+
ScriptSender
98+
------------
99+
100+
The ``ScriptSender`` class opens a tcp socket on the remote PC whose single purpose it is to answer
101+
with a URScript code snippet on a "*request_program*" request. The script code itself has to be
102+
given to the class constructor.
103+
104+
Use this class in conjunction with the `External Control URCap
105+
<https://github.com/UniversalRobots/Universal_Robots_ExternalControl_URCap>`_ which will make the
106+
corresponding request when starting a program on the robot that contains the **External Control**
107+
program node. In order to work properly, make sure that the IP address and script sender port are
108+
configured correctly on the robot.
109+
110+
Other public interface functions
111+
--------------------------------
112+
113+
This section shall explain the public interface functions that haven't been covered above
114+
115+
116+
check_calibration()
117+
^^^^^^^^^^^^^^^^^^^
118+
119+
This function opens a connection to the primary interface where it will receive a calibration
120+
information as the first message. The checksum from this calibration info is compared to the one
121+
given to this function. Connection to the primary interface is dropped afterwards.
122+
123+
sendScript()
124+
^^^^^^^^^^^^
125+
126+
This function sends given URScript code directly to the secondary interface. The
127+
``sendRobotProgram()`` function is a special case that will send the script code given in the
128+
``RTDEClient`` constructor.
129+
130+
DashboardClient
131+
---------------
132+
133+
The ``DashboardClient`` wraps the calls on the `Dashboard server <https://www.universal-robots.com/articles/ur-articles/dashboard-server-e-series-port-29999/>`_
134+
directly into C++ functions.
135+
136+
After connecting to the dashboard server by using the ``connect()`` function, dashboard calls can be
137+
sent using the ``sendAndReceive()`` function. Answers from the dashboard server will be returned as
138+
string from this function. If no answer is received, a ``UrException`` is thrown.
139+
140+
Note: In order to make this more useful developers are expected to wrap this bare interface into
141+
something that checks the returned string for something that is expected. See the
142+
`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.

doc/conf.py

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Configuration file for the Sphinx documentation builder.
4+
#
5+
# This file does only contain a selection of the most common options. For a
6+
# full list see the documentation:
7+
# http://www.sphinx-doc.org/en/master/config
8+
9+
# -- Path setup --------------------------------------------------------------
10+
11+
# If extensions (or modules to document with autodoc) are in another directory,
12+
# add these directories to sys.path here. If the directory is relative to the
13+
# documentation root, use os.path.abspath to make it absolute, like shown here.
14+
#
15+
# import os
16+
# import sys
17+
# sys.path.insert(0, os.path.abspath('.'))
18+
19+
import os
20+
import catkin_pkg.package
21+
22+
catkin_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
23+
catkin_package = catkin_pkg.package.parse_package(
24+
os.path.join(catkin_dir, catkin_pkg.package.PACKAGE_MANIFEST_FILENAME)
25+
)
26+
27+
# -- Project information -----------------------------------------------------
28+
29+
project = "ur_client_library"
30+
copyright = "2022, Felix Exner"
31+
author = "Felix Exner"
32+
33+
# The short X.Y version
34+
version = catkin_package.version
35+
# The full version, including alpha/beta/rc tags
36+
release = catkin_package.version
37+
38+
39+
# -- General configuration ---------------------------------------------------
40+
41+
# If your documentation needs a minimal Sphinx version, state it here.
42+
#
43+
# needs_sphinx = '1.0'
44+
45+
# Add any Sphinx extension module names here, as strings. They can be
46+
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
47+
# ones.
48+
extensions = []
49+
50+
# Add any paths that contain templates here, relative to this directory.
51+
templates_path = [".templates"]
52+
53+
# The suffix(es) of source filenames.
54+
# You can specify multiple suffix as a list of string:
55+
#
56+
# source_suffix = ['.rst', '.md']
57+
source_suffix = ".rst"
58+
59+
# The master toctree document.
60+
master_doc = "index"
61+
62+
# The language for content autogenerated by Sphinx. Refer to documentation
63+
# for a list of supported languages.
64+
#
65+
# This is also used if you do content translation via gettext catalogs.
66+
# Usually you set "language" from the command line for these cases.
67+
language = None
68+
69+
# List of patterns, relative to source directory, that match files and
70+
# directories to ignore when looking for source files.
71+
# This pattern also affects html_static_path and html_extra_path.
72+
exclude_patterns = []
73+
74+
# The name of the Pygments (syntax highlighting) style to use.
75+
pygments_style = None
76+
77+
78+
# -- Options for HTML output -------------------------------------------------
79+
80+
# The theme to use for HTML and HTML Help pages. See the documentation for
81+
# a list of builtin themes.
82+
#
83+
html_theme = "agogo"
84+
85+
# Theme options are theme-specific and customize the look and feel of a theme
86+
# further. For a list of options available for each theme, see the
87+
# documentation.
88+
#
89+
# html_theme_options = {}
90+
91+
# Add any paths that contain custom static files (such as style sheets) here,
92+
# relative to this directory. They are copied after the builtin static files,
93+
# so a file named "default.css" will overwrite the builtin "default.css".
94+
html_static_path = [".static"]
95+
96+
# Custom sidebar templates, must be a dictionary that maps document names
97+
# to template names.
98+
#
99+
# The default sidebars (for documents that don't match any pattern) are
100+
# defined by theme itself. Builtin themes are using these templates by
101+
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
102+
# 'searchbox.html']``.
103+
#
104+
# html_sidebars = {}
105+
106+
107+
# -- Options for HTMLHelp output ---------------------------------------------
108+
109+
# Output file base name for HTML help builder.
110+
htmlhelp_basename = "ur_client_librarydoc"
111+
112+
113+
# -- Options for LaTeX output ------------------------------------------------
114+
115+
latex_elements = {
116+
# The paper size ('letterpaper' or 'a4paper').
117+
#
118+
# 'papersize': 'letterpaper',
119+
# The font size ('10pt', '11pt' or '12pt').
120+
#
121+
# 'pointsize': '10pt',
122+
# Additional stuff for the LaTeX preamble.
123+
#
124+
# 'preamble': '',
125+
# Latex figure (float) alignment
126+
#
127+
# 'figure_align': 'htbp',
128+
}
129+
130+
# Grouping the document tree into LaTeX files. List of tuples
131+
# (source start file, target name, title,
132+
# author, documentclass [howto, manual, or own class]).
133+
latex_documents = [
134+
(
135+
master_doc,
136+
"ur_client_library.tex",
137+
"ur\\_client\\_library Documentation",
138+
"Felix Exner",
139+
"manual",
140+
)
141+
]
142+
143+
144+
# -- Options for manual page output ------------------------------------------
145+
146+
# One entry per manual page. List of tuples
147+
# (source start file, name, description, authors, manual section).
148+
man_pages = [(master_doc, "ur_client_library", "ur_client_library Documentation", [author], 1)]
149+
150+
151+
# -- Options for Texinfo output ----------------------------------------------
152+
153+
# Grouping the document tree into Texinfo files. List of tuples
154+
# (source start file, target name, title, author,
155+
# dir menu entry, description, category)
156+
texinfo_documents = [
157+
(
158+
master_doc,
159+
"ur_client_library",
160+
"ur_client_library Documentation",
161+
author,
162+
"ur_client_library",
163+
"One line description of project.",
164+
"Miscellaneous",
165+
)
166+
]
167+
168+
169+
# -- Options for Epub output -------------------------------------------------
170+
171+
# Bibliographic Dublin Core info.
172+
epub_title = project
173+
174+
# The unique identifier of the text. This can be a ISBN number
175+
# or the project homepage.
176+
#
177+
# epub_identifier = ''
178+
179+
# A unique identification for the text.
180+
#
181+
# epub_uid = ''
182+
183+
# A list of files that should not be packed into the epub file.
184+
epub_exclude_files = ["search.html"]

0 commit comments

Comments
 (0)