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

Python API: Reorder Item Tree

#1
I have a large workstation with many targets, all with a common parent reference frame. I often want to adjust what order they appear in the item tree.

My current process for reordering is:
1. Record the names and poses of all my targets into lists
2. Delete all targets
3. Sort my list
4. Re-create each target in the correct order using `robolink.Robolink.AddTarget`

The performance of this operation is poor, due to the large number of Python API calls.

I would like to be able to just do something like this.
1. Get list of my targets: `my_targets = robolink.Robolink.ItemList(filter=robolink.ITEM_TYPE_TARGET)`
2. Sort the list: `my_sorted_targets = my_custom_sorter(my_targets)`
3. Use a built-in API call to reorder the targets: `robolink.Robolink.ReorderItems(items=my_sorted_targets, itemparent=my_targets[0].Parent())`

--------------------------------------------------------------

An alternative approach that works less well for my specific application but is potentially more useful for the wider community would be expanding the option for batch operations to additional methods. Robolink.Delete() is a good example of an existing method that already supports batch operations.

Batch operations would address the main issues causing poor performance (creating and changing poses of many targets) in my current process. However, they would not clean up my code nearly as much as a method to reorder targets.

In this proposal, the batch alternative to `AddTarget` would be `AddTargets`, which would take the same arguments but as lists instead of singles. A full suite of batch methods would be required to make this approach workable. In my case, I would specifically need a batch version of `setPose` that takes `list[Mat]` and `list[robolink.Item]`.

In this case, it is key that there are true API calls that accept lists rather than just wrapping the non-batch version in another Python method. This is because the point is to speed up the process of batch operations.
Code:
# BAD!
def AddTargets(names:list[str], itemparents:list[robolink.Item]):
    return [AddTarget(name, itemparent=parent for name, parent in zip(names, parents)]
#2
One option to reorder targets is to use the setParent function. This will place the item at the end of the current list of child items attached to the parent.

For example, this will place Target 3 at the end of the list where Target 4 is attached:
Code:
item_reorder = RDK.Item('Target 3')
item_ref = RDK.Item('Target 4')
item_reorder.setParent(item_ref.Parent())

Also, another way to do so is by using the Reorder parameter (probably not very well documented). For example, this will place Target 3 after Target 4:
Code:
item_reorder = RDK.Item('Target 3')
item_ref = RDK.Item('Target 4')
item_reorder.setParam("Reorder", item_ref)

And if you add the Before string, it will place Target 3 before Target 4. Example:
Code:
item_reorder = RDK.Item('Target 3')
item_ref = RDK.Item('Target 4')
item_reorder.setParam("ReorderBefore", item_ref)
#3
`setParent()` works perfectly.

Thanks, Albert!
  




Users browsing this thread:
1 Guest(s)