Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adapt RTDE output recipe based on robot response #221

Merged
merged 5 commits into from
Nov 25, 2024

Conversation

remi-siffert-ocado
Copy link
Contributor

Not all RTDE outputs are available in all SW versions. When working with a fleet of robots with heterogeneous SW versions it's not practical to have multiple RTDE output recipes to account for this.
This PR aims at solving this problem by adapting the RTDE output recipe on-the-fly based on the robot response to the RTDE request. Outputs which are not available for this particular SW version are simply removed from the output recipe and a trimmed down output recipe is sent to the robot.

Potential issues / improvements:

  • variables removed from the output recipe only cause a warning. When these variables are "optional" this is a fine behaviour but it could potentially be masking incorrect variable names. It could be better to make this behaviour configurable.
  • an alternate implementation could be to hardcode the compatibility information for RTDE outputs in data_package.cpp and validate the output recipe beforehand. This seems less flexible though.
  • the same logic could potentially be applied to the input recipe. Having optional inputs seems less likely though.

@remi-siffert-ocado remi-siffert-ocado marked this pull request as draft October 31, 2024 15:22
@remi-siffert-ocado remi-siffert-ocado marked this pull request as ready for review October 31, 2024 18:32
@fmauch
Copy link
Collaborator

fmauch commented Nov 5, 2024

variables removed from the output recipe only cause a warning. When these variables are "optional" this is a fine behaviour but it could potentially be masking incorrect variable names. It could be better to make this behaviour configurable.

This popped into my mind immediately. I think this should not be the default behavior, but some opt-in feature.

an alternate implementation could be to hardcode the compatibility information for RTDE outputs in data_package.cpp and validate the output recipe beforehand. This seems less flexible though

This reminds me of our discussion in #213 (comment).

the same logic could potentially be applied to the input recipe. Having optional inputs seems less likely though.

I agree with both.

@remi-siffert-ocado
Copy link
Contributor Author

remi-siffert-ocado commented Nov 5, 2024

This popped into my mind immediately. I think this should not be the default behavior, but some opt-in feature.

That's fair. I'll add a parameter to the UrDriver constructor unless there's a better way.

This reminds me of our discussion in #213 (comment).

Yes it's definitely related. I feel that auto-negotiating based on the robot response is a bit more flexible than having a fixed list.

@urfeex
Copy link
Member

urfeex commented Nov 7, 2024

That's fair. I'll add a parameter to the UrDriver constructor unless there's a better way.

I'd like to avoid adding more parameters to the constructor. In the past this has proven to a) blow up the constructor argument list quite significantly and b) easily introduce troubles in API compatibility which is why we have so many constructors at the moment.

With #218 we could create the driver with a minimal recipe and then reset the RTDEClient with the full recipe. In the reset method we could also add a flag for automatically drop incompatible fields. What would you think about that option?

@remi-siffert-ocado
Copy link
Contributor Author

I'd like to avoid adding more parameters to the constructor. In the past this has proven to a) blow up the constructor argument list quite significantly and b) easily introduce troubles in API compatibility which is why we have so many constructors at the moment.
With #218 we could create the driver with a minimal recipe and then reset the RTDEClient with the full recipe. In the reset method we could also add a flag for automatically drop incompatible fields. What would you think about that option?

I agree that adding a parameter to the constructor is not ideal. It's probably a good idea to separate the construction from the configuration of the RTDE communication. I would argue that in this case the constructor should not contain anything related to RTDE anymore. It should be replaced with a distinct configureRTDECommunication / resetRTDEClient method that has to be called before startRTDECommunication.

The main problem is how do we handle the dependencies between these MRs. I see 3 options:

  1. merge Adapt RTDE output recipe based on robot response #221 as-is with the caveat that the behaviour is not configurable
  2. add a constructor parameter in Adapt RTDE output recipe based on robot response #221 that will be removed once Allow resetting the RTDE client #218 is merged
  3. somehow combine Adapt RTDE output recipe based on robot response #221 and Allow resetting the RTDE client #218 into a bigger MR

What's your take on this @urfeex?

@urfeex
Copy link
Member

urfeex commented Nov 8, 2024

  1. would be my choice, though I would suggest finishing Allow resetting the RTDE client #218 first and then rebasing and adapting Adapt RTDE output recipe based on robot response #221 ontop of that. However, given my current workload I am not sure how quickly I will be able to implement the missing things on Allow resetting the RTDE client #218. Would it be ok with you letting this PR hang for one more week and then we use option 1. if I haven't come around finishing Allow resetting the RTDE client #218?

@urfeex
Copy link
Member

urfeex commented Nov 13, 2024

I've finished #218. I just need a review from one of my colleagues to get that merged then we can modify this to build upon that. I would suggest adding a flag to the resetRTDEClient method.

@remi-siffert-ocado
Copy link
Contributor Author

remi-siffert-ocado commented Nov 14, 2024

I've finished #218. I just need a review from one of my colleagues to get that merged then we can modify this to build upon that. I would suggest adding a flag to the resetRTDEClient method.

Thanks for the follow-up!

I am still trying to understand how we can use this resetRTDEClient method effectively in the context of the ROS2 driver. The current sequence of calls in the ROS2 driver is: instantiate the UrDriver and call startRTDECommunication once the first time we want to read RTDE data. With the current implementation where the RTDE output recipe is automatically adapted there's no additional call required and we're able to support different UR SW versions.
For this behaviour to be configurable the sequence has to change to: instantiate the UrDriver, call resetRTDEClient with a flag based on the hardware parameters and then call startRTDECommunication. Is that what you had in mind?

@urfeex
Copy link
Member

urfeex commented Nov 15, 2024

For this behaviour to be configurable the sequence has to change to: instantiate the UrDriver, call resetRTDEClient with a flag based on the hardware parameters and then call startRTDECommunication. Is that what you had in mind?

I was not necessarily having the ROS 2 driver in mind, since you didn't mention that so far. Changing the recipe with the ROS 2 driver will only be useful if the driver is modified, as well, right? I think the recipe we have in there should be rather backwards-compatible.

But yes, adding the reset call after the UrDriver object has been created should work. That's also what I implemented #218 for initially.

@remi-siffert-ocado
Copy link
Contributor Author

I was not necessarily having the ROS 2 driver in mind, since you didn't mention that so far.

That's my bad but yes the ROS 2 driver is the main use case I had in mind for this change.

Changing the recipe with the ROS 2 driver will only be useful if the driver is modified, as well, right? I think the recipe we have in there should be rather backwards-compatible.

Given that the recipe used in the ROS2 driver is configurable via the hardware parameters (https://github.com/UniversalRobots/Universal_Robots_ROS2_Driver/blob/main/ur_robot_driver/src/hardware_interface.cpp#L380) any output recipe is actually possible.
In our context we definitely have backwards-incompatible data in the output recipe. But another way of doing this would be to keep the default output recipe in UrDriver and instantiate another RTDEClient outside of UrDriver for additional data if required. I'll add a configuration parameter to the constructor of RTDEClient and resetRTDEClient I think this should cover all bases.

@remi-siffert-ocado remi-siffert-ocado force-pushed the adapt-rtde-recipe branch 2 times, most recently from 43d652c to 7d36c20 Compare November 18, 2024 22:25
@remi-siffert-ocado
Copy link
Contributor Author

Implemented the changes we discussed. Let me know what you think.

Copy link
Member

@urfeex urfeex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking good, thank you! However, I would prefer making the change in an API compatible manor if possible.

As you've noticed in the tests you had to update the client constructor usages.

If you merge in / rebase onto current master the example runs should also succeed which should give a succeeding pipeline.

include/ur_client_library/rtde/rtde_client.h Outdated Show resolved Hide resolved
include/ur_client_library/ur/ur_driver.h Outdated Show resolved Hide resolved
src/rtde/rtde_client.cpp Outdated Show resolved Hide resolved
src/rtde/rtde_client.cpp Outdated Show resolved Hide resolved
@remi-siffert-ocado
Copy link
Contributor Author

Thanks for the comments! Addressed everything in b9f8484.

Copy link
Member

@urfeex urfeex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking good now, thank you very much!

@urfeex urfeex merged commit fc79456 into UniversalRobots:master Nov 25, 2024
20 of 23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants