Skip to content

Added 4 methods for extracting meshes from links in RobotModel #25

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

Merged
merged 7 commits into from
Dec 2, 2024

Conversation

yck011522
Copy link
Contributor

As part of my effort in updating compass fab, particularly related to a two new features

  • representing and using kinematic ToolModels in planning backend.
  • visualization of robots with user-changable RobotBaseFrame.

I have come to the repeated need of extracting visual and collision meshes from each Link in a RobotModel, therefore I have introduced these four methods in the RobotModel class for doing that. This kind of methods are lacking in the current class. Consider the fact that it is not straightforward to navigate the nested URDF elements inside a Link, I think it is reasonable to provide such method for both users and developers.

Four methods in total:
RobotModel.get_link_visual_meshes
RobotModel.get_link_collision_meshes
RobotModel.get_link_visual_meshes_joined
RobotModel.get_link_collision_meshes_joined
I'm in favor of separating the _visual and _collision instead of having a single function with a boolean input to indicate visual vs collision, this is up for discussion.


A few notes for the future:

  • Each Link can have a list of Visual and a list of Collision elements. The list can also be empty.
  • link.visual and link.collision are actually a list.
  • In each of these element, element.geometry.shape is a list of shapes that can be MeshDescriptor, CapsuleProxy, SphereProxy , CylinderProxy or BoxProxy.
  • I have only dealt with the MeshDescriptor because it is very rare that others are used in existing packages for industrial robot, or used in custom tools build by users. However other shapes also have .mesh method to return mesh representation, if there is a need to include them in the future.

What type of change is this?

  • Bug fix in a backwards-compatible manner.
  • New feature in a backwards-compatible manner.
  • Breaking change: bug fix or new feature that involve incompatible API changes.
  • Other (e.g. doc update, configuration, etc)

Checklist

Put an x in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code.

  • I added a line to the CHANGELOG.md file in the Unreleased section under the most fitting heading (e.g. Added, Changed, Removed).
  • I ran all tests on my computer and it's all green (i.e. invoke test).
  • I ran lint on my computer and there are no errors (i.e. invoke lint).
  • I have added tests that prove my fix is effective or that my feature works.
  • I have added necessary documentation (if appropriate)

@yck011522 yck011522 requested a review from chenkasirer October 30, 2024 08:43
Copy link
Member

@chenkasirer chenkasirer left a comment

Choose a reason for hiding this comment

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

comments are from me and @gonzalocasas

Comment on lines 1049 to 1052
# Note: the MeshDescriptor.meshes object supports a list of compas meshes.
if isinstance(shape, MeshDescriptor):
# There can be multiple mesh in a single MeshDescriptor
for mesh in shape.meshes:
Copy link
Member

Choose a reason for hiding this comment

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

there is a LinkGeometry._get_item_meshes that can be used to handle this, including any primitive shapes.
see example usage in

meshes = LinkGeometry._get_item_meshes(item)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, I am aware but I don't like that code path with the coerce to tuple thing.
And I think my code is more extendable if in the future other Descriptors are supported.

Copy link
Member

Choose a reason for hiding this comment

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

the code currently doesn't support primitives (i.e. proxies of Sphere, Box etc).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

right, this is a comment right? Or?

Copy link
Member

Choose a reason for hiding this comment

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

To me it would make sense to cover all kinds of link geometries already in this PR, or could you explain why you focus on MeshDescriptor and see all others as future extension?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, so you mean by using meshes = LinkGeometry._get_item_meshes(item) we can cover the other Descriptors too?

Okay, we can do that too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

@yck011522
Copy link
Contributor Author

@chenkasirer I guess I resolved everything ?

@yck011522
Copy link
Contributor Author

I think I found the thing that didn't work.

  • FrameProxy does not forward the __len__ function that Frame had.
  • This made the Frame.eq not work.

This was the reason I had made the function to get a normal frame back...
2024-11-26 18_37_05
2024-11-26 18_35_36

This is how the __eq__ function was implemented.

I'm not sure how the proxy technology works, but I think it doesn't deal with the special private functions. Probably there are more of these being affected.

2024-11-26 18_39_16

@yck011522
Copy link
Contributor Author

I have changed my mind regarding the meshes_at_link_origin, indeed, the meshes can have different origins even if they belong to the same link. for example link.visual can have multiple Visual elements that each can have different Visual.origin. And consider that the get_link_meshes returns all meshes of a link in a flat list, there is probably no reason to return the meshes 'un-transformed'.

Note that this transformation is indeed slow on large visual meshes, so application side should take care of not over doing it.

Note to future self: Use RobotCellLibrary.ur10e() to test the drawing of links where meshes are not at link origin.

Copy link
Member

@chenkasirer chenkasirer left a comment

Choose a reason for hiding this comment

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

lgtm
@yck011522 thanks for taking care of all the review comments~
I might create an issue or two for follow up, don't want to hold this PR any longer.

@yck011522
Copy link
Contributor Author

@chenkasirer Cool. Thanks

@yck011522 yck011522 merged commit 897f3f1 into main Dec 2, 2024
14 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.

2 participants