Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5

setPose is not working when automatic Render is used

#1
I've got code running inside a loop that is limited by execution speed (no timer). The relevant passage is below.

Code:
my_target = RDK.AddTarget('my_target', itemparent=my_item_parent)
my_target.setParam('metadata', my_binary_data)     # where my_binary_data is a string of variable length, but roughly 50 characters, encoded using utf-8
my_target.setPose(robomath.KUKA_2_Pose(my_coords))
my_target.setParentStatic(my_other_reference_frame)


With the passage above, I observed that some of the targets had the coordinates zeroed out and were placed at the location of their parent reference frames. However, when I stepped through with the debugger, all targets were created properly.

The issue disappears after placing a `time.sleep(0.1)` between lines 1 and 2 of the snippet above. (Immediately after the `RDK.AddTarget` line.)
UPDATE: the specifics of the delay requirement seem to be somewhat inconsistent. I have also experienced needing to add a delay between lines 3 and 4 (.setPose and .setParentStatic).

The unmodified passage was previously working without issue. I only started noticing the problem after switching to a VPN that is slightly slower than my usual connection, but I haven't been able to do a direct comparison to confirm that the VPN causes this. However, I assume the RoboDK API was designed to handle a slower VPN, so this is probably a bug.

Windows 10 Pro
Python 3.11.1
robodk (the python module) 5.5.5
RoboDK (the GUI) 5.5.4

Please let me know if additional information is needed.
#2
I assume you are using the API with the Automatic Render option activated. Can you confirm?

In this case, I recommend you to try replacing the 100 ms timeout by a call to the Update function:

Code:
RDK.Update()
#3
I am not sure which one the Automatic Render option is.
- I called RDK.Render(True) immediately before this passage.
- In my workstation, in Tools > Options > Other, Auto render delay is set to the maximum (1000).

Calling RDK.Update() works, thanks!
1. Would you be able to provide more information about what this is doing and when it is necessary to use?
2. Will there be a fix for this behavior, or is this expected?

Since I got this slower VPN connection, I noticed similar strange behavior appeared in some of my other routines as well. If you can provide any additional guidance about this behavior to help me determine where I need to add the RDK.Update()'s, that would be much appreciated. For example, can I just add RDK.Update() to the end of the AddTarget() and setPose() methods in robolink > Robolink, or will that slow other things down too much?
#4
When you manage the Render events yourself via the API, the Update function can help you in specific circumstances when you change the parent of an item shortly before or after changing the pose. The Update function propagates the position of all items and allows proper calculation of all items with respect to each other.

It is important to call the Update function to propagate the updated position of all items with respect to each other. The update function should be very fast.
#5
I made the changes everywhere that I am changing parents and setting a new pose in close proximity. So far, things seem to be working as-expected again.

For a cleaner solution, is there a better way to manage render events rather than RDK.Render(False)? What I really want to do is avoid provoking a screen render. I don't want to interfere with the normal automatic operation of whatever routine RDK.Update() is provoking.


While the RDK.Update() solution is fine as a workaround, I wanted to share my thoughts on robustness and maintainability to hopefully yield a better outcome moving forward. I understand if a fix for this isn't a priority, but I wanted to at least get a discussion going. I can also open a GitHub issue, if that's preferred.


It feels to me like this solution has Code Smell.
  • I'm copy-pasting RDK.Update() before and after all lines containing ".setParent" and I have to continue to remember to add more RDK.Update()'s when building new features, with the consequence being a silent failure that requires a slow network connection to troubleshoot.
  • As an API user, my initial assumption is that determining when the positions of items in the tree has gone stale should be handled behind-the-scenes, not by users of the API.
  • The fact that whether or not this problem occurs depends on the network speed is a red flag for robustness.
#6
Thank you for your feedback. The RoboDK API should be fast if you use the API locally (RoboDK and client API on the same machine). What can take time is the Render option which will always update the RoboDK 3D view when you change something in your project (not when you retrieve information from the RoboDK station).

Therefore, I recommend you to set the always Render flag back to default (On/activated), after you have done your computationally intensive tasks. Maybe we should add a warning in the docs. Also, if there is a task you perform often and it is slow we can look into creating a new API call to accelerate it.

To better clarify, you can call Update only after you move objects or the relationship between them (and this is only useful if you are planning to do further calculations or change relationships that depend on your recent changes). We could do this automatically on RoboDK's end but it would defeat the purpose of turning the Always Render flag off to maximize speed. I don't recommend you to increase the Auto render delay that much as RoboDK can run the update and render calculations while you do other calculations with your API.

If you are looking to make the RoboDK API as fast as possible you can also use the Plugin Interface, which gives you access to the RoboDK API and the RoboDK UI in Qt. The API calls are the low level C++ RoboDK functions which does not involve sockets. You can find more information here:
https://robodk.com/doc/en/PlugIns/index.html
#7
Hi Albert,

This occurred again today, but with a much faster network connection and an auto-render delay of only 100ms (RDK.Render was set to False, like last time). I believe that I am having trouble anticipating exactly when RDK.Update() is required and ending up with non-homogenous (corrupt?) poses with inconsistencies between the poses in the API and the GUI.

You previously stated that "you can call Update only after you move objects or the relationship between them (and this is only useful if you are planning to do further calculations or change relationships that depend on your recent changes).". This points me in the right direction, but if you could provide a more strict definition for what conditions exactly require RDK.Update(), that would be really helpful. For example, a rule like "If you modify parent/child relationships and change the pose of any affected frames, you MUST call RDK.Update() if you cannot guarantee that the two calls are separated by at least the auto-render delay time." would be really helpful for adding only as many RDK.Update()'s as are strictly required.

Can you please also clarify if actions such as changing the pose of frame_a with respect to its own parent, then immediately changing the pose of frame_a's child, may cause similar problems?

Thanks!
#8
Changing relative poses should not be a problem if you do it in bulk and it should work well even if you don't call Update.

The main issue is with internal absolute poses (functions such as PoseAbs, setPoseAbs, setParentStatic). These poses only get recalculated when you call Update.

Also, changing the relative pose of an item (setPose) will update the absolute pose of the same item (setPoseAbs) based on the last known absolute location of that same item (since the last Update event).
#9
Okay, thank you, Albert!
  




Users browsing this thread:
1 Guest(s)