npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

urdf-loader-extension

v0.12.3

Published

URDF Loader for THREE.js and webcomponent viewer

Downloads

64

Readme

urdf-loader-extension

基于urdf-loader库的扩展库,保留urdf-loader库现有功能。 但是urdf-loader库只解析threeJS渲染3D模型所使用到的数据,不会把urdf中自定义的数据附加到Object3D对象中。 本库主要就扩展了在解析urdf时,可以读取urdf中自定的数据,且是钩子形式,用户可以根据自己的需要在钩子中写自己的扩展逻辑。

Based on the extension library of urdf-loader library, the existing functions of urdf-loader library are retained. However, the URDf-loader library only parses the data used by threeJS to render the 3D model, and does not attach the custom data from urdf to the Object3D object. This library is mainly extended when parsing urdf, you can read custom data in urdf, and is in the form of hooks, users can write their own extension logic according to their own needs in the hook.

Utilities for loading URDF files into THREE.js and a Web Component that loads and renders the model.

Use

Basic Use

Loading a URDF file from a server.

import { LoadingManager } from 'three';
import URDFLoader from 'urdf-loader-extension';

// ...init three.js scene...

const manager = new LoadingManager();
const loader = new URDFLoader( manager );
loader.packages = {
    packageName : './package/dir/'            // The equivalent of a (list of) ROS package(s):// directory
};
loader.load(
  'T12/urdf/T12.URDF',                    // The path to the URDF within the package OR absolute
  robot => {

    // The robot is loaded!
    scene.add( robot );

  }
);

Extend hook usage(new)

这部分是扩展的内容,如不使用,也不影响原urdf-loader的功能 This part is the content of the extension. If not used, it will not affect the function of the original urdf-loader

/**
 * robotHook
 * 这个钩子可以处理<robot name="***"> robot标签下的所有内容
 * This hook will handle anything under <robot name="***"> robot tag
 */
loader.robotHook = (robotNodes, linkMap, jointMap, curRobotObject3D) => {
    // robotNodes Array<DOMElement[]>
    // 数组形式,每个元素为robot下的子集,DOM节点形式
    // Array form, each element is a subset under robot, DOM node form
    /**
     * robotNodes example
     * 例如获取所有transmission子集元素
     * For example, get all transmission subset elements
     * */
    const transmissions = robotNodes.filter(c => c.nodeName.toLowerCase() === 'transmission');


    // linkMap Object<linkName string, linkObject Object3D>
    // 对象形式所有子集link元素集合
    // Object form a collection of all subset link elements
    /**
     * linkMap example
     * 例如在每个link对象上加上自定义的字段field1
     * For example, add a custom field field1 to each link object
     * 通常会做一些更有意义的处理,例如把link标签下的自定义标签的值加入到link对象中
     * Usually, you do something more meaningful, such as adding the value of the custom tag under the link tag to the link object
     * */
    Object.values(linkMap).forEach(link => {
        link['field1'] = 'your value'
    })


    // jointMap Object<jointName string, jointObject Object3D>
    // 对象形式所有子集joint元素集合
    // Object form a collection of all subset joint elements
    /**
     * jointMap example
     * 例如在每个link对象上加上自定义的字段field2
     * For example, add a custom field field2 to each link object
     * 通常会做一些更有意义的处理,例如把其他挂载到joint上的transmission或自定义描述字段加入到joint对象中
     * Usually something more meaningful is done, such as adding other transmission to the joint or custom description fields to the joint object
     * */
    Object.values(jointMap).forEach(joint => {
        joint['field2'] = 'your value'
    })

    // curRobotObject3D Object3D
    // 整个urdf的Object3D对象
    // Object3D object for the entire urdf
    /**
     * curRobotObject3D example
     * 例如把所有的transmission数据单独保存在Object3D对象上
     * For example, we store all transmission data in a separate object called Object3D
     */
    const transmissionObjects = {}
    transmissions.forEach(t => {
        const name = t.getAttribute('name')
        transmissionObjects['name'] = name
        transmissionObjects['children'] = t.children
    })
    curRobotObject3D['transmissions'] = transmissionObjects
}

/**
 * jointHook
 * 这个钩子可以处理<link>标签下的所有内容,用于读取link标签下的自定义标签内容或对link对象特殊处理
 * This hook can handle anything under a <link> tag, be used to read custom tag content under a link tag, or do special things with link objects
 * 会便利执行执行joint元素下的所有子元素,每便利一个子元素都会执行一下jointHook
 * The convenience execution executes all the child elements under the joint element, and each convenience child element executes the jointHook
 */
loader.jointHook = (curJointNode, curJointObject3D) => {
    // curJointNode <DOMElement>
    // 当前joint DOM节点对象
    // Current joint DOM node object
    /**
     * 例如获取当前节点的标签名
     * For example, get the tag name of the current node
     */
    const nodeName = curJointNode.nodeName.toLowerCase();

    // curJointObject3D <Object3D>
    // 当前joint 的Object3D对象
    // The current joint's Object3D object
    /**
     * 往当前joint对象上添加自定义字段 field3
     * Add the custom field field3 to the current joint object
     */
    curJointObject3D['field3'] = 'your value'
}

/**
 * linkHook
 * linkHook钩子用法同jointHook
 * linkHook hooks are used the same way as jointHook
 * 在这个钩子中可以处理linkVisualHook和linkCollisionHook这两个钩子的事情,但是需要判断curLinkChildNode的nodeName为visual何collision来找到这两个节点
 * You can handle linkVisualHook and linkCollisionHook in this hook, but you need to determine that the nodeName of curLinkChildNode is visual and collision to find these two nodes
 */
loader.linkHook = (curLinkChildNode, curLinkObject3D) => {}

/**
 * linkVisualHook
 * 此钩子用于在便利link数据时,对其visual子元素的额外处理
 * This hook is used to facilitate additional processing of the link data's visual children
 */
loader.linkVisualHook = (curLinkVisualNode, curLinkVisualObject3D) => {}

/**
 * linkCollisionHook
 * 此钩子用于在便利link数据时,对其collision子元素的额外处理
 * This hook is used for additional processing of its collision child elements when facilitating link data
 */
loader.linkCollisionHook = (curLinkCollisionNode, curLinkCollisionObject3D) => {}

Custom Mesh Loader & Error Handling

Implementing custom error handling and / or adding a custom loader for meshes can be done using the loadMeshCb callback.

import { GLTFLoader } from 'three/examples/loaders/GLTFLoader.js';
import URDFLoader from 'urdf-loader';

// ...init three.js scene...

const loader = new URDFLoader();
loader.loadMeshCb = function( path, manager, onComplete ) {

    const gltfLoader = new GLTFLoader( manager );
    gltfLoader.load(
        path,
        result => {

            onComplete( result.scene );

        },
        undefined,
        err => {
        
            // try to load again, notify user, etc
        
            onComplete( null, err );
        
        }
    );

};
loader.load( 'T12/urdf/T12.URDF', robot => {

    // The robot is loaded!
    scene.add( robot );

} );

From Xacro

Using XacroParser to process a Xacro URDF file and then parse it.

import { LoaderUtils } from 'three';
import { XacroLoader } from 'xacro-parser';
import URDFLoader from 'urdf-loader';

// ...init three.js scene...

const url = './path/to/file.xacro';
const xacroLoader = new XacroLoader();
xacroLoader.load( url, xml => {

    const urdfLoader = new URDFLoader();
    urdfLoader.workingPath = LoaderUtils.extractUrlBase( url );

    const robot = urdfLoader.parse( xml );
    scene.add( robot );

} );

Adjusting Joint Angles

robot.setJointValue( jointName, jointAngle );

// or

robot.joints[ jointName ].setJointValue( jointAngle );

API

URDFOptions

List of options available on the URDFLoader class.

.packages

packages = '' : String | Object | ( pkg : String ) => String

The path representing the package:// directory(s) to load package:// relative files.

If the argument is a string, then it is used to replace the package:// prefix when loading geometry.

To specify multiple packages an object syntax is used defining the package name to the package path:

{
  "package1": "./path/to/package1",
  "package2": "./path/to/package2",
  ...
}

If the setting is set to a function then it takes the package name and is expected to return the package path.

.loadMeshCb

loadMeshCb = null :
    (
        pathToModel : string,
        manager : LoadingManager,
        onComplete : ( obj : Object3D, err ?: Error ) => void
    ) => void

An optional function that can be used to override the default mesh loading functionality. The default loader is specified at URDFLoader.defaultMeshLoader.

pathToModel is the url to load the model from.

manager is the THREE.js LoadingManager used by the URDFLoader.

onComplete is called with the mesh once the geometry has been loaded.

.fetchOptions

fetchOptions = null : Object

An optional object with the set of options to pass to the fetch function call used to load the URDF file.

.workingPath

workingPath = '' : string

The path to load geometry relative to.

Defaults to the path relative to the loaded URDF file.

.parseVisual

parseVisual = true : boolean

An optional value that can be used to enable / disable loading meshes for links from the visual nodes. Defaults to true.

.parseCollision

parseCollision = false : boolean

An optional value that can be used to enable / disable loading meshes for links from the collision nodes. Defaults to false.

URDFLoader

.constructor

constructor( manager : LoadingManager )

Constructor. Manager is used for transforming load URLs and tracking downloads.

.load

load(
    urdfpath : string,
    onComplete : (robot : URDFRobot) => void,
    onProgress? : () => void,
    onError? : (error : Error) => void
) : void

Loads and builds the specified URDF robot in THREE.js.

Takes a path to load the urdf file from, a func to call when the robot has loaded, and a set of options.

.loadAsync

loadAsync( urdfpath : string ) : Promise<URDFRobot>

Promise-wrapped version of load.

.parse

parse( urdfContent : string | Document | Element ) : URDFRobot

Parses URDF content and returns the robot model. Takes an XML string to parse and a set of options.

If the XML document has already been parsed using DOMParser then either the returned Document or root Element can be passed into this function in place of the string, as well.

Note that geometry will not necessarily be loaded when the robot is returned.

URDFJoint

extends Object3D

An object representing a robot joint.

.name

name : string

The name of the joint.

.jointType

.jointType : string

The type of joint. Can only be the URDF types of joints.

.limit

.limit : { lower : number, upper : number }

An object containing the lower and upper constraints for the joint.

.axis

axis : Vector3

The axis described for the joint.

.angle

readonly

angle : number

The current position or angle for joint.

.ignoreLimits

ignoreLimits : boolean

Whether or not to ignore the joint limits when setting a the joint position.

.mimicJoints

mimicJoints : URDFMimicJoints[]

A list of joints which mimic this joint. These joints are updated whenever this joint is.

.setJointValue

setJointValue( ...jointValues : (number | null)[] ) : Boolean

Sets the joint value(s) for the given joint. The interpretation of the value depends on the joint type. If the joint value specifies an angle it must be in radians. If the value specifies a distance, it must be in meters. Passing null for any component of the value will skip updating that particular component.

Returns true if the joint or any of its mimicking joints changed.

URDFMimicJoint

extends URDFJoint

An object representing a robot joint which mimics another existing joint. The value of this joint can be computed as value = multiplier * other_joint_value + offset.

.mimicJoint

mimicJoint : String

The name of the joint which this joint mimics.

.offset

offset : Number

Specifies the offset to add in the formula above. Defaults to 0 (radians for revolute joints, meters for prismatic joints).

.multiplier

multiplier : Number

Specifies the multiplicative factor in the formula above. Defaults to 1.0.

URDFLink

extends Object3D

.name

name : string

The name of the link.

URDFRobot

extends URDFLink

Object that describes the URDF Robot.

.robotName

robotName : string

The name of the robot described in the <robot> tag.

.links

links : { [key] : URDFLink }

A dictionary of linkName : URDFLink with all links in the robot.

.joints

joints : { [key] : URDFJoint }

A dictionary of jointName : URDFJoint with all joints in the robot.

.colliders

colliders : { [key] : Object3D }

A dictionary of colliderName : Object3D with all collision nodes in the robot.

.visual

visual : { [key] : Object3D }

A dictionary of visualName : Object3D with all visual nodes in the robot.

.frames

joints : { [key] : URDFJoint }

A dictionary of all the named frames in the robot including links, joints, colliders, and visual.

.setJointValue

setJointValue( name : String, value : Number ) : Boolean

Sets the joint value of the joint with the given name. Returns true if the joint changed.

.setJointValues

setJointValues( jointValueDictionary : Object ) : Boolean

Sets the joint values for all the joints in the dictionary indexed by joint name. Returns true if a joint changed.

urdf-viewer Element

<!-- Register the Element -->
<script href=".../urdf-viewer-element.js"></script>
<script>customElements.define('urdf-viewer', URDFViewer)</script>

<body>
  <urdf-viewer package=".../package/dir/" urdf="T12/urdf/T12.URDF" up="Z+" display-shadow ambient-color="red"></urdf-viewer>
</body>

Attributes

package

Corresponds to the package parameter in URDFLoader.load. Supported are:

  1. Single package:

    <!-- 1. Example for single package named `default_package` -->
    <urdf-viewer package=".../path/to/default_package" ...></urdf-viewer>

    Fallback within 1: If the target package within the package:// relative files do not match the default path it is assumed that the default path is the parent folder that contains the target package(s).

    <!-- 1. Example for single package named `default_package` with fallback: -->
    <urdf-viewer package=".../path/to/parent" ...></urdf-viewer>
    <!-- since `parent` does not match `default_package`
         the path ".../path/to/parent/default_package" is assumed -->
  2. Serialized package map:

    E.g. if the meshes of a URDF are distributed over mutliple packages.

    <!-- 2. Example for serialized package map that contains `package1` and `package2` -->
    <urdf-viewer package="package1:.../path/to/package1, package2:.../path/to/package1" ...></urdf-viewer>

urdf

Corresponds to the urdfpath parameter in URDFLoader.load.

The element uses fetch options { mode: 'cors', credentials: 'same-origin' } to load the urdf file.

ignore-limits

Whether or not hte display should ignore the joint limits specified in the model when updating angles.

up

The axis to associate with "up" in THREE.js. Values can be [+-][XYZ].

display-shadow

Whether or not the render the shadow under the robot.

ambient-color

The color of the ambient light specified with css colors.

auto-redraw

Automatically redraw the model every frame instead of waiting to be dirtied.

no-auto-recenter

Recenter the camera only after loading the model.

Properties

All of the above attributes have corresponding camel case properties.

.jointValues

jointValues : Object

Sets or gets the jointValues of the robot as a dictionary of joint-name to radian pairs.

Functions

.setJointValue

setJointValue( jointName : String, ...jointValues : (number | null)[] ) : void

Sets the given joint to the provided value(s). See URDFJoint.setJointValue.

.setJointValues

setJointValues( jointValueDictionary : Object ) : void

Sets all joint names specified as keys to radian angle value.

.redraw

redraw() : void

Dirty the renderer so the element will redraw next frame.

.recenter

recenter() : void

Recenter the camera to the model and redraw.

Events

'urdf-change'

Fires when the URDF has changed and a new one is starting to load.

'ignore-limits-change'

Fires when the ignore-limits attribute changes.

'urdf-processed'

Fires when the URDF has finished loading and getting processed.

'geometry-loaded'

Fires when all the geometry has been fully loaded.

Running the Example

Install Node.js and NPM.

Run npm install.

Run npm start.

Visit localhost:9080/javascript/example/dev-bundle/ to view the page.

LICENSE

The software is available under the Apache V2.0 license.

Copyright © 2020 California Institute of Technology. ALL RIGHTS RESERVED. United States Government Sponsorship Acknowledged. Neither the name of Caltech nor its operating division, the Jet Propulsion Laboratory, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.