urdf-loaders

repository·master·Indexed 21 days ago

https://github.com/gkjohnson/urdf-loaders

A set of specialized loading tools to import URDF (Unified Robot Description Format) robot descriptions into THREE.js (JavaScript) and Unity (C#) environments. It includes the urdf-loader package (v0.13.1) for web use and a Unity-specific implementation. Key features include support for ROS package path mapping, custom mesh loading callbacks for formats like GLTF, Xacro file parsing via xacro-parser, and APIs for programmatically adjusting joint angles.

Tokens
10.6K
Snippets
28
Records
43
Agent score
73%

What's inside urdf-loaders

  1. Overview of urdf-loaders

    master

    The urdf-loaders repository provides tools for loading URDF (Unified Robot Description Format) files into two primary environments:

    1. Unity (C#): Located in the ./unity/Assets/URDFLoader/ directory.
    2. THREE.js (JavaScript): Located in the ./javascript/ directory.

    The repository also includes example URDF files based on the JPL ATHLETE robot.

  2. Use flipped models for inverted robot configurations

    master
    The repository includes _flipped variants of the URDF ATHLETE models. These variants invert the revolute joint axes. Use these models if you need to represent the robot in a configuration where the legs are attached to the bottom of the chassis rather than the top.
  3. Understand Mimic Joints

    master

    A URDFMimicJoint is a joint that automatically follows the movement of another joint based on a formula: value = multiplier * other_joint_value + offset.

    Properties:

    • mimicJoint: The name of the source joint being mimicked.
    • multiplier: The multiplicative factor (defaults to 1.0).
    • offset: The additive offset (defaults to 0). For revolute joints, this is in radians; for prismatic, in meters.
  4. Basic usage of URDFLoader to load URDF files

    master

    To load a URDF file into a THREE.js scene, instantiate URDFLoader. You can provide a THREE.js LoadingManager to the constructor.

    Crucially, if your URDF references assets (like meshes) located in specific directories, you must configure the loader.packages object. This object maps package names to their corresponding directory paths, mimicking the ROS package structure.

    Use the .load() method, which takes the path to the URDF file and a callback function that receives the loaded robot object.

    import { LoadingManager } from 'three';
    import URDFLoader from 'urdf-loader';
    
    // ...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)
    };
    loader.load(
      'T12/urdf/T12.URDF',                    // The path to the URDF within the package OR absolute
      robot => {
    
        // The robot is loaded!
        scene.add( robot );
    
      }
    );
  5. Load URDF files from Xacro files

    master

    To load a .xacro file, you must first process it using xacro-parser.

    1. Use XacroLoader.load() to fetch and parse the Xacro file into an XML string.
    2. In the callback, instantiate URDFLoader.
    3. Set urdfLoader.workingPath using LoaderUtils.extractUrlBase(url) to ensure relative paths within the Xacro are resolved correctly.
    4. Call urdfLoader.parse(xml) with the XML string to get the robot object.
    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 );
    
    } );
  6. Run the urdf-loader example project

    master

    To run the local development environment for the examples:

    1. Ensure Node.js and NPM are installed.
    2. Run npm install to install dependencies.
    3. Run npm start to launch the development server.
    4. Open your browser to http://localhost:9080/javascript/example/dev-bundle/.
    npm install
    npm start
  7. Implement custom mesh loading and error handling

    master

    You can intercept the mesh loading process by providing a function to loader.loadMeshCb. This callback is triggered whenever the loader encounters a mesh path.

    The callback receives three arguments:

    1. path: The string path to the mesh file.
    2. manager: The THREE.js LoadingManager instance.
    3. onComplete: A callback function that must be called to signal the completion of the custom loading process. It accepts (result, error) as arguments.

    This is useful for using specific loaders (like GLTFLoader) or implementing custom retry logic and error reporting.

    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 => {
        scene.add( robot );
    });
  8. Basic usage of urdf-loader in Unity

    master

    You can load a URDF robot into Unity using either the .Load method (providing a file path) or the .Parse method (providing the raw URDF string content). Both methods require a packages parameter to resolve package:// URDF paths to local file system paths.

    To resolve package paths, provide a Dictionary<string, string> where the key is the package name and the value is the local directory path.

    Dictionary<string, string> packages = new Dictionary<string, string>();
    packages["r2_description"] = "./path/to/r2_description";
    packages["val_description"] = "./path/to/val_description";
    
    // Using .Load with a file path
    URDFRobot robot = URDFLoader.Load(".../path/to/urdf", packages);
    
    // Using .Parse with raw string content
    StreamReader reader = new StreamReader(".../path/to/urdf");
    URDFRobot robot = URDFLoader.Parse(reader.ReadToEnd(), packages);
  9. Configure URDFLoader options

    master

    When instantiating or using URDFLoader, you can configure several options to handle package paths and mesh loading:

    • packages: Defines how package:// URDF prefixes are resolved. Can be a string (replacement), an object (mapping names to paths), or a function (pkg: string) => string.
    • workingPath: The base path for loading geometry. Defaults to the path relative to the URDF file.
    • parseVisual: (Boolean, default true) Enables/disables loading meshes from <visual> nodes.
    • parseCollision: (Boolean, default false) Enables/disables loading meshes from <collision> nodes.
    • loadMeshCb: An optional callback to override default mesh loading logic.
    • fetchOptions: Options passed to the internal fetch call.
    const loader = new URDFLoader();
    loader.packages = {
      'my_robot_pkg': '/assets/robot_pkg'
    };
    loader.parseCollision = true;
  10. Resolve ROS package:// paths in URDFLoader

    master

    When a URDF file uses the package:// prefix for mesh paths (common in ROS), you must configure the packages option in URDFLoader so the loader knows where to find those files.

    Configuration Methods

    1. Using a String (Single Package) If all your packages reside in one directory, provide that directory as a string. The loader will assume the package name is a subdirectory of this path.

    const loader = new URDFLoader();
    loader.packages = '/path/to/ros_workspace/src';

    2. Using an Object (Multiple Packages) Map specific ROS package names to their absolute filesystem paths.

    const loader = new URDFLoader();
    loader.packages = {
        'my_robot_description': '/path/to/robot_pkg',
        'sensor_msgs': '/path/to/sensor_pkg'
    };

    3. Using a Function (Dynamic Resolver) Provide a callback that takes a package name and returns the resolved path.

    const loader = new URDFLoader();
    loader.packages = (pkgName) => {
        return `/custom/path/${pkgName}`;
    };
  11. Understand the URDFRobot data structure

    master

    A URDFRobot instance acts as the root container for all parsed URDF elements. It extends URDFLink and organizes the robot's components into searchable dictionaries (maps) keyed by their names in the URDF file:

    • links: A map of URDFLink objects.
    • joints: A map of URDFJoint objects.
    • colliders: A map of URDFCollider objects.
    • visual: A map of URDFVisual objects.
    • frames: A map of Object3D objects representing the coordinate frames.
  12. How URDFMimicJoints work

    master

    A URDFMimicJoint is a special type of joint that automatically updates its own state based on the state of another joint (the mimicJoint). The relationship is defined by the formula:

    value = (other_joint_value * multiplier) + offset

    • multiplier: A multiplicative factor (defaults to 1.0).
    • offset: An additive offset (defaults to 0).

    When you call setJointValue on the parent joint, all registered mimicJoints are automatically updated.