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

Add joint limit and inertial link data #299

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

dkozma
Copy link

@dkozma dkozma commented Nov 21, 2024

This PR adds the following:

  • Adds inertial parsing support for links according to the specification
  • Adds effort and velocity limit support for joints according to the specification
  • Adds a meshPath variable so downstream applications can track when all meshes are loaded if they want to (I didn't add this functionality due to not wanting to add additional dependencies, however this was the change I needed to do so).
  • Unit tests for parsing changes
  • Update umd files

Copy link
Owner

@gkjohnson gkjohnson left a comment

Choose a reason for hiding this comment

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

Great, thank you! I've added a few comments. We'll want to update the URDFLink documentation in the README, as well.

Comment on lines +21 to +23
origin: { xyz: Vector3 | null, rpy: Vector3 | null } | null;
mass: Number | null;
inertia: { ixx: Number, ixy: Number, ixz: Number, iyy: Number, iyz: Number, izz: Number } | null;
Copy link
Owner

Choose a reason for hiding this comment

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

We shouldn't initialize these to null if they are not in the file. Lets use the default values listed in the specification.


}

export interface URDFLink extends Object3D {

isURDFLink: true;
urdfNode: Element | null;
inertial: URDFInertial | null;
Copy link
Owner

Choose a reason for hiding this comment

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

Lets make sure this is always present, as well.

@@ -30,7 +41,7 @@ export interface URDFJoint extends Object3D {
jointType: 'fixed' | 'continuous' | 'revolute' | 'planar' | 'prismatic' | 'floating';
angle: Number;
jointValue: Number[];
limit: { lower: Number, upper: Number }; // TODO: add more
limit: { lower: Number, upper: Number, effort: Number | null, velocity: Number | null };
Copy link
Owner

Choose a reason for hiding this comment

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

Same comment - lets use the default values.

@@ -544,6 +584,7 @@ class URDFLoader {
// file path is null if a package directory is not provided.
if (filePath !== null) {

group.meshPath = filePath;
Copy link
Owner

@gkjohnson gkjohnson Nov 22, 2024

Choose a reason for hiding this comment

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

Can you explain the need for this field a bit further? And why do you need to resolved, absolute path rather than the local path provided in the URDF?

Copy link
Author

@dkozma dkozma Nov 23, 2024

Choose a reason for hiding this comment

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

Essentially I use this as an identifier to figure when a particular link mesh (e.g. a referenced STL or DAE file) in the URDF has loaded, so that I can do operations on the geometry. I believe the loadAsync call resolves only when the URDF file has been loaded and parsed, however at that time the geometries referenced in the links still seem to be empty.

If there is another way to do this, please let me know so I can try using that approach instead of doing this.

Copy link
Owner

@gkjohnson gkjohnson Nov 24, 2024

Choose a reason for hiding this comment

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

It's true that the promise only resolves once the robot hierarchy is loaded, not once all the geometry is ready. You can use the LoadingManger to detect when the full model is loaded, though:

let robot;
const manager = new LoadingManager();
manager.onComplete = () => {

    // everything in the robot model is loaded

};

const loader = new URDFLoader( manager );
loader.loadAsync( url ).then( result => {

    robot = result;

} );

Not the most ergonomic but it works, is easy to wrap, and will fire when all textures are loaded, as well. If you'd like something more built in we can talk about a flag that that can be toggled to await all the geometry loading.

You can also replace the mesh loader with one that will process the geometry when it's loaded:

loader.loadMeshCb = ( path, manager, onComplete ) => {

  // load mesh, process it, call onComplete

}; 

const rpy = origin ? origin.getAttribute('rpy') : null;
const mass = subNodes.find(sn => sn.nodeName.toLowerCase() === 'mass');
const inertia = subNodes.find(sn => sn.nodeName.toLowerCase() === 'inertia');
target.inertial = origin || mass || inertia ? {
Copy link
Owner

Choose a reason for hiding this comment

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

Per the other comments, lets make sure this inertial field is already fully initialized with the correct defaults. And then this block can just overwrite any fields that are present in the file.

@@ -410,6 +420,36 @@ class URDFLoader {
target.urdfName = target.name;
target.urdfNode = link;

// Extract the attributes
children.forEach(n => {
Copy link
Owner

@gkjohnson gkjohnson Nov 23, 2024

Choose a reason for hiding this comment

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

Let's follow the pattern used elsewhere in the file:

const inertialNode = children.find(n => n.nodeName.toLowerCase() === 'inertial');
if ( inertialNode !== null ) {

  [ ...inertialNode.children ].forEach( child => {

    const type = n.nodeName.toLowerCase();
    if ( type === 'origin' ) { /* ... */ }
    else if ( type === 'mass' ) { /* ... */ }
    // and so on...
 
  } );

}

@dkozma
Copy link
Author

dkozma commented Nov 23, 2024

Thanks for taking a look - I'll make these changes during the week!

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