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

setPose gets slower as the number of targets increase

#1
Using the Python API, I am creating a very large number of targets (>10k) from stored data. Example code is below.


Code:
# set target_parent before snippet starts
# __all_dicts has the following structure:
'''
{
    'name_0': {
            'pose': # a pose
            'metadata': # a dict containing other information to be stored with each target item
          },
    'name_1': {
            'pose': # a different pose
            'metadata': # another dict with same keys but different values
          },
    ...
}
'''
__i = 0
for __one_name, __one_dict in __all_dicts.items():
    print(str(i))
    __t = RDK.AddTarget(__one_name, itemparent=target_parent)
    __t.setPose(__one_dict['pose'])
    __t.setParam('metadata', json.dumps(__one_dict['metadata'].encode('utf-8'))
    __i += 1

During execution, I notice that things start off pretty speedy, but after creating about 2k targets, things slow down dramatically (10x?). I have not done detailed timing profiling, but just judging by where it stops when I pause execution using the debugger, it was consistently stopping on the line `__t.setPose(...)`.

Is there anything I can do to speed up the execution of the setPose method, or am I running into a fundamental limit of Python and I just need to switch to C if I want to speed up further?
#2
Calling setPose (or any other function that changes the state of the simulation) provokes a render event. This can be slow if your project is complex. You can speed things up by turning off render for the API.

Example to turn off rendering while you are operating through the API:
Code:
RDK.Render(False)
... set pose for as many targets as you need
RDK.Render(True)
#3
Hi Albert, apologies -- I should have shared more of my code. I was already using RDK.Render(False) prior to creating any targets.

Since my last post, I also discovered that this occurs in another place where I am creating >10k targets inside a for loop. However, this time, it seems to be spending the most time on the __t.setPost() line. Again, things go okay until I get about 20% of the way through the 10k targets, then things slow down a lot.

Code:
# target_parent is a frame in the workstation that was already defined
self.RDK.Render(False)
for __i, __line in enumerate(lines_of_imported_file):
    [__target_pose, __metadata] = parseLine(__line)
    __t = RDK.AddTarget("t_" + str(__i) + itemparent=target_parent)
    __t.setParam('metadata', json.dumps(__metadata).encode('utf-8'))
    __t.setPose(__target_pose)
    self.RDK.Update()

Is this behavior expected in both instances?
#4
You don't need to call Update if you are changing the pose of targets you just created.

Can you try linking the target to the reference frame and the right robot?
Code:
__t = RDK.AddTarget("t_" + str(__i), itemparent=target_parent, itemrobot=robot)
If it does not work, could you send us an example so we can reproduce it?
#5
I tried removing the RDK.Update() (moved it to the end, after the loop completes). That did not resolve the issue.

I also added a robot to the workstation (this workstation typically does not have a robot in it) and linked all targets to the robot as you suggested. This also did not resolve the issue.

The code I provided here is part of a much larger codebase and would probably require approval from my company's customer to share, even privately over email. Would you be able to describe the information you are looking for in more detail so I can try to package that into a non-sensitive and portable example? Alternatively, I would likely be allowed to give a live (non-recorded) demo on a call if that is easier.
#6
Something worth trying is to increase the auto render delay:
RoboDK->Tools->Options->Other->Auto render delay
Please read the Forum Guidelines before posting!
Find useful information about RoboDK by visiting our Online Documentation.
#7
Hi Sam, it's sitting at 100ms. I previously had it at 1000ms, but after this discussion with Albert, I decreased it. What value would you recommend I try? https://robodk.com/forum/Thread-setPose-...er-is-used
#8
I made a quick test and.. it seems to be related to the tree rendering.
Can you try collapsing the parent of the targets before loading them?
See below.

Code:
RDK = robolink.Robolink()

RDK.Render(False)
parent = RDK.AddFrame('Frame 1')
parent.setParam('Tree', 'Collapse') # This is the important part!
for i in range(10000):
    t = RDK.AddTarget(f"Target {i}", parent)
    t.setPose(robomath.transl(i, 0, 0))
Please read the Forum Guidelines before posting!
Find useful information about RoboDK by visiting our Online Documentation.
#9
Hi Sam, looks like that fixed it. Thanks for the workaround!

Let me know if there's going to be a fix in a future version so I can clean up my code.
  




Users browsing this thread:
1 Guest(s)