Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #419 +/- ##
==========================================
- Coverage 75.33% 75.01% -0.32%
==========================================
Files 102 103 +1
Lines 5120 5328 +208
Branches 544 553 +9
==========================================
+ Hits 3857 3997 +140
- Misses 980 1065 +85
+ Partials 283 266 -17
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
6529df0 to
24aa5ab
Compare
7cb3675 to
b70a72c
Compare
src/rtde/rtde_parser.cpp
Outdated
| if (result == nullptr || result->getType() != PackageType::RTDE_DATA_PACKAGE) | ||
| { | ||
| result = std::make_unique<DataPackage>(recipe_, protocol_version_); | ||
| URCL_LOG_WARN("The passed result pointer is empty or does not contain a DataPackage. A new DataPackage will " |
There was a problem hiding this comment.
- Let's us ensure that this warning only applies when there is something unexpected happening
There was a problem hiding this comment.
With the latest changes I could not encounter this during normal operation. I've added a more descriptive output in that case so if it ever happened, we know a bit better what happened.
|
bugbot run |
|
Skipping Bugbot: Bugbot is disabled for this repository |
|
bugbot run |
3c6efbe to
798efbb
Compare
| if (result == nullptr || result->getType() != PackageType::RTDE_DATA_PACKAGE) | ||
| { | ||
| if (result == nullptr) | ||
| { | ||
| URCL_LOG_WARN("The passed result pointer is empty. A new DataPackage will " | ||
| "have to be allocated. Please pass a pre-allocated DataPackage if you expect a DataPackage " | ||
| "would be sent."); | ||
| } | ||
| else | ||
| { | ||
| URCL_LOG_WARN("Passed a pre-allocated RTDE package of type %u while a DataPackage was received. A new " | ||
| "DataPackage will have to be allocated. Please pass a pre-allocated DataPackage if you expect " | ||
| "a DataPackage would be sent.", | ||
| result->getType()); | ||
| } | ||
| result = std::make_unique<DataPackage>(recipe_, protocol_version_); |
There was a problem hiding this comment.
- Consider make one if elseif case instead of an if else in an if
There was a problem hiding this comment.
The result = std::make_unique<DataPackage>(recipe_, protocol_version_); is common for both cases, which is why I catch those cases in the outer if. Depending on what's the cause for a not correctly allocated data package the output is different, hence the inner if.
Merging both layers into a single if...else if would require duplicating the important line potentially increasing the error missing one case when updating the code in the future. My opinion on this isn't that strong, if you think that the following structure is better, we can go with that:
if (result == nullptr)
{
URCL_LOG_WARN("The passed result pointer is empty. A new DataPackage will "
"have to be allocated. Please pass a pre-allocated DataPackage if you expect a DataPackage "
"would be sent.");
result = std::make_unique<DataPackage>(recipe_, protocol_version_);
}
else if (result->getType() != PackageType::RTDE_DATA_PACKAGE)
{
URCL_LOG_WARN("Passed a pre-allocated RTDE package of type %u while a DataPackage was received. A new "
"DataPackage will have to be allocated. Please pass a pre-allocated DataPackage if you expect "
"a DataPackage would be sent.",
result->getType());
result = std::make_unique<DataPackage>(recipe_, protocol_version_);
}
urrsk
left a comment
There was a problem hiding this comment.
Look very good. Just a small comment
…imeout is being violated
Co-authored-by: Rune Søe-Knudsen <41109954+urrsk@users.noreply.github.com>
… unknown key Initializing a robot with keys that the specific version doesn't know is unaffected by this. This affects only configurations where users specify a key that is unknown to the client library.
When no package can be retreived in the given timeout, don't log an error. That hasn't been there before, as well.
Otherwise there is a race condition when checking whether the thread is joinable.
0486b21 to
45eb65f
Compare
That test was not adding a real scenario and now that we have the real reconnection tests using the fake server, we can remove that test.
45eb65f to
bd1d00e
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
This is a refactor of RTDE communication effectively improving two things:
There's currently some documentation and testing missing, hence the draft status.
Note
High Risk
Touches core RTDE networking/parsing/IO concurrency and changes public APIs with deprecations; regressions could impact real-time data integrity, reconnection behavior, and write semantics under load.
Overview
RTDE read path is refactored to avoid per-cycle heap allocations and reduce overhead.
RTDEClientno longer relies on thePipelinefor reads; it usesURProducerdirectly plus a double-buffered background read thread, and introducesstart(bool read_packages_in_background)with newgetDataPackage(DataPackage&/unique_ptr&, timeout)andgetDataPackageBlocking(...)APIs while deprecating the allocatinggetDataPackage(timeout)overload.RTDE parsing and packages are updated to support reuse and stricter validation.
Parser/IProduceradd single-product parse/tryGet overloads,RTDEParseris split into a newrtde_parser.cppwith a prealloc-friendly parse path (vector-based parse deprecated),RTDEPackageexposesgetType(), andDataPackageswitches from anunordered_mapto an ordered vector store, initializes empty data on construction, validates recipe keys (throwing newRTDEInvalidKeyException), adds type checking onsetData, and improvestoString()formatting.RTDE write path is refactored for fewer allocations and batching.
RTDEWriterreplaces the moodycamel queue with double-buffered storage + condition variable, addssendPackage()for sending a fully-prepared package, preallocates register key strings, and resets mask fields after sending; it now throws oninit()/setInputRecipe()while running.API consumers, docs, and tests are migrated to the new allocation-free patterns. Examples and documentation now show preallocating
DataPackageand using the new read modes;ExampleRobotWrapperremoves its custom RTDE consumer thread and forwards the background-read choice toUrDriver. Tests are expanded/updated for background vs blocking read, reconnection, invalid keys/conflicts,DataPackageparsing/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.
Written by Cursor Bugbot for commit 4e23395. This will update automatically on new commits. Configure here.