# How to properly load a URDF file using urdf-loader in aframe?

**URL:** <https://discourse.threejs.org/t/how-to-properly-load-a-urdf-file-using-urdf-loader-in-aframe/65320>\
**Category:** Questions\
**Tags:** aframe, urdf\
**Created:** [May 9, 2024, 2:01pm UTC](https://discourse.threejs.org/t/how-to-properly-load-a-urdf-file-using-urdf-loader-in-aframe/65320 "2024-05-09T14:01:24Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![addy1997](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/addy1997/32/34740_2.png) [@addy1997](https://discourse.threejs.org/u/addy1997)\
**Post date:** [May 9, 2024, 2:01pm UTC](https://discourse.threejs.org/t/how-to-properly-load-a-urdf-file-using-urdf-loader-in-aframe/65320/1 "2024-05-09T14:01:24Z")

</div>

I am trying to load a [URDF file](https://github.com/StanfordASL/PandaRobot.jl/blob/f891b31b5b83db6104b4dea820c3672e5387b902/deps/Panda/panda.urdf) in aframe scene to visualize it on VR. The code for aframe component is:

```javascript
<script type="importmap"> { "imports": {
                    "urdf-loader": "https://cdn.jsdelivr.net/npm/urdf-loader@0.12.1/umd/URDFLoader.js",
                    "three": "https://unpkg.com/three@0.150.1/build/three.module.js",
                    "three/addons/": "https://unpkg.com/three@0.150.1/examples/jsm/"
                } }
    </script>
    <script type="module">
      import 'urdf-loader';
      import {
        STLLoader
      } from 'three/addons/loaders/STLLoader';
      import {
        WebGLRenderer,
        Mesh,
        MathUtils,
        Bone,
        Vector3
      } from 'three';
      AFRAME.registerComponent('load-panda-urdf', {
        init: function() {
          const manager = new THREE.LoadingManager();
          const loader = new URDFLoader(manager);
          loader.load('https://raw.githubusercontent.com/StanfordASL/PandaRobot.jl/master/deps/Panda/panda.urdf', // The path to the URDF within the package OR absolute
            robot => {
              // The robot is loaded!
              this.el.sceneEl.object3D.add(robot);
            });
        },
      })
    </script>

```

I get these warnings

```javascript
URDFLoader: Could not load model at /Panda/meshes/collision/link0.obj.
No loader available

URDFLoader: Could not load model at /Panda/meshes/collision/link1.obj.

URDFLoader: Could not load model at /Panda/meshes/collision/link2.obj.

URDFLoader: Could not load model at /Panda/meshes/collision/link3.obj.

URDFLoader: Could not load model at /Panda/meshes/collision/link4.obj.

```

I went through [the documentation of the urdf-loaders project](https://github.com/gkjohnson/urdf-loaders/tree/master/javascript#use) on github but couldn’t find any fix for this. How do I fix this?

PS:

This is the [jsfiddle](https://jsfiddle.net/adwait3301/6kzupx38/21/) to try the code

It says “no loader available” in the warnings but even afrer importing the OBJLoader from threejs I am not sure where to use it.

---

<div class="post-metadata">

**Author:** ![gkjohnson](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/gkjohnson/32/2298_2.png) [@gkjohnson](https://discourse.threejs.org/u/gkjohnson)\
**Post date:** [May 13, 2024, 3:54am UTC](https://discourse.threejs.org/t/how-to-properly-load-a-urdf-file-using-urdf-loader-in-aframe/65320/2 "2024-05-13T03:54:37Z")

</div>

The reason it’s not working is because you’re missing some basic set up which is described and shown at the very top of the [URDF Loader README](https://github.com/gkjohnson/urdf-loaders/tree/master/javascript#basic-use).

1. You need to list the directories for the ROS packages used in the URDF file so the loader knows where to resolve mesh paths to:

```js
const loader = new URDFLoader( manager );
loader.packages = {
    packageName : './package/dir/' // The equivalent of a (list of) ROS package(s):// directory
};

```

1. By default only STL and DAE files are supported by the URDF loader since these are (were?) the most common formats used in the ecosystem. So as the error states, the OBJ files cannot be loaded and you need to provide a custom `loadMeshCb` to handle OBJ file extensions. You can see how here in the [Custom Mesh Loading](https://github.com/gkjohnson/urdf-loaders/tree/master/javascript#custom-mesh-loader--error-handling) section of the docs. You’ll need to load OBJ instead of GLTF, though:

```js
loader.loadMeshCb = function( path, manager, onComplete ) {

    const loader = new OBJLoader( manager );
    loader.load(
        path,
        result => {

            onComplete( result.scene );

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

};

```

---

<div class="post-metadata">

**Author:** ![addy1997](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/addy1997/32/34740_2.png) [@addy1997](https://discourse.threejs.org/u/addy1997)\
**Post date:** [May 13, 2024, 12:33pm UTC](https://discourse.threejs.org/t/how-to-properly-load-a-urdf-file-using-urdf-loader-in-aframe/65320/3 "2024-05-13T12:33:12Z")

</div>

Hi @gkjohnson,

Do you mean something like this?

```javascript

<script type="importmap">
                { "imports": {
                    "urdf-loader": "https://cdn.jsdelivr.net/npm/urdf-loader@0.12.1/umd/URDFLoader.js",
                    "three": "https://unpkg.com/three@0.150.1/build/three.module.js",
    				"three/addons/": "https://unpkg.com/three@0.150.1/examples/jsm/"
                } }
    </script>

    <script type="module">

        import 'urdf-loader';
        import { OBJLoader } from 'three/addons/loaders/OBJLoader';
        import { WebGLRenderer, Mesh, MathUtils, Bone, Vector3 } from 'three';

        AFRAME.registerComponent('load-panda-urdf', {
            init: function () {
                const URDF_PATH = './assets/Panda/panda.urdf';
                const manager = new THREE.LoadingManager();
                const loader = new URDFLoader(manager);
                loader.packages = {
                    package1: './assets/Panda/meshes/collision/finger.obj',
                    package2: './assets/Panda/meshes/collision/hand.obj',
                    package3: './assets/Panda/meshes/collision/link0.obj',
                    package10: './assets/Panda/meshes/collision/link1.obj',
                    package5: './assets/Panda/meshes/collision/link2.obj',
                    package6: './assets/Panda/meshes/collision/link3.obj',
                    package7: './assets/Panda/meshes/collision/link4.obj',
                    package8: './assets/Panda/meshes/collision/link5.obj',
                    package9: './assets/Panda/meshes/collision/link6.obj',
                    package10: './assets/Panda/meshes/collision/link7.obj'
                }
                loader.loadMeshCb = function (URDF_PATH, manager, onComplete) {

                    const loader = new OBJLoader(manager);
                    loader.load(
                        URDF_PATH,
                        result => {

                            onComplete(result.scene);

                        },
                        undefined,
                        err => {

                            // try to load again, notify user, etc

                            onComplete(null, err);

                        }
                    );

                };
            },
        })

    </script>

```

My folder structure ![image](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/0/1/014b287df59b56b7565a2ab6292d7d6bd469ca17.png)

[panda.urdf](https://discourse.threejs.org/uploads/short-url/s02xvR0QY4c3YPAHWckjRhsGJxU.urdf) (8.1 KB)

---

<div class="post-metadata">

**Author:** ![gkjohnson](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/gkjohnson/32/2298_2.png) [@gkjohnson](https://discourse.threejs.org/u/gkjohnson)\
**Post date:** [May 14, 2024, 12:45am UTC](https://discourse.threejs.org/t/how-to-properly-load-a-urdf-file-using-urdf-loader-in-aframe/65320/4 "2024-05-14T00:45:31Z")

</div>

A ROS package is the root directory where the package contents are. In the URDF and other ROS files this directory is referenced via the `package://` protocol in the file. In this case it’s `package://Panda` so you’ll need to specify where the `package://Panda` directory is so the URDF loader can resolve the mesh file paths:

> ```js
> loader.packages = {
> Panda: 'https://raw.githubusercontent.com/StanfordASL/PandaRobot.jl/f891b31b5b83db6104b4dea820c3672e5387b902/deps/Panda/',
> }
> 
> ```
