You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Refactor rtde parsing for RT and performance improvements (#419)
This is a refactor of RTDE communication effectively improving two
things:
- No more heap memory allocations during communication once everything
is setup
- Reduced parsing and access times of RTDE data that reduces the time of
read and send operations
There is a backwards-compatible implementation that will produce a deprecation warning when compiling.
**RTDE read path is refactored to avoid per-cycle heap allocations and
reduce overhead.** `RTDEClient` no longer relies on the `Pipeline` for
reads; it uses `URProducer` directly plus a double-buffered background
read thread, and introduces `start(bool read_packages_in_background)`
with new `getDataPackage(DataPackage&/unique_ptr&, timeout)` and
`getDataPackageBlocking(...)` APIs while deprecating the allocating
`getDataPackage(timeout)` overload.
**RTDE parsing and packages are updated to support reuse and stricter
validation.** `Parser`/`IProducer` add single-product parse/tryGet
overloads, `RTDEParser` is split into a new `rtde_parser.cpp` with a
prealloc-friendly parse path (vector-based parse deprecated),
`RTDEPackage` exposes `getType()`, and `DataPackage` switches from an
`unordered_map` to an ordered vector store, initializes empty data on
construction, validates recipe keys (throwing new
`RTDEInvalidKeyException`), adds type checking on `setData`, and
improves `toString()` formatting.
**RTDE write path is refactored for fewer allocations and batching.**
`RTDEWriter` replaces the moodycamel queue with double-buffered storage
+ condition variable, adds `sendPackage()` for sending a fully-prepared
package, preallocates register key strings, and resets mask fields after
sending; it now throws on `init()`/`setInputRecipe()` while running.
**API consumers, docs, and tests are migrated to the new
allocation-free patterns.** Examples and documentation now show
preallocating `DataPackage` and using the new read modes;
`ExampleRobotWrapper` removes its custom RTDE consumer thread and
forwards the background-read choice to `UrDriver`. Tests are
expanded/updated for background vs blocking read, reconnection, invalid
keys/conflicts, `DataPackage` parsing/toString, and parser
single-product mode.
**CI and tooling tweaks:** workflow disables URSim port forwarding,
gates coverage uploads on successful build, shortens example sleep
between runs, and improves fake RTDE server thread shutdown safety.
---------
Co-authored-by: Rune Søe-Knudsen <41109954+urrsk@users.noreply.github.com>
The recipes can be either passed as a filename or as a list of strings directly. E.g. the
49
+
following will work
32
50
33
-
The recipes can be either passed as a filename or as a list of strings directly. E.g. the
34
-
following will work
51
+
.. code-block:: c++
52
+
53
+
rtde_interface::RTDEClient my_client(
54
+
ROBOT_IP,
55
+
notifier,
56
+
{"timestamp", "actual_q"},
57
+
{"speed_slider_mask", "speed_slider_fraction"}
58
+
);
59
+
60
+
.. note::
61
+
``timestamp`` will always be a part of the output recipe and will be added afterwards, if not defined. As the ``timestamp`` used for verifying the connectivity.
35
62
36
-
.. code-block:: c++
63
+
Reading data
64
+
------------
37
65
38
-
rtde_interface::RTDEClient my_client(
39
-
ROBOT_IP,
40
-
notifier,
41
-
{"timestamp", "actual_q"},
42
-
{"speed_slider_mask", "speed_slider_fraction"}
43
-
);
66
+
After calling ``my_client.start()``, data can be read from the
67
+
``RTDEClient`` by calling ``getDataPackage()`` (with background thread running) or ``getDataPackageBlocking()`` (without background thread running) respectively.
44
68
45
-
Inside the ``RTDEclient`` data is received in a separate thread, parsed by the ``RTDEParser`` and
46
-
added to a pipeline queue.
69
+
Remember that, when not using a background thread, data has to be polled regularly, as the robot
70
+
will shutdown RTDE communication if the receiving side doesn't empty its buffer.
47
71
48
-
Right after calling ``my_client.start()``, it should be made sure to read the buffer from the
49
-
``RTDEClient`` by calling ``getDataPackage()`` frequently. The Client's queue can only contain a
50
-
restricted number of items at a time, so a ``Pipeline producer overflowed!`` error will be raised
51
-
if the buffer isn't read frequently enough.
72
+
Writing data
73
+
------------
52
74
53
75
For writing data to the RTDE interface, use the ``RTDEWriter`` member of the ``RTDEClient``. It can be
54
76
retrieved by calling ``getWriter()`` method. The ``RTDEWriter`` provides convenience methods to write
@@ -83,11 +105,11 @@ an empty input recipe, like this:
83
105
// Alternatively, pass an empty filename when using recipe files
0 commit comments