Xacro support for repository-based building blocks like vendor part DBs

This is to discuss a new xacro feature I and a few new users are working on. We would like a simpler way for new users to construct robots (URDF files) without requiring CAD skills, knowledge of inertias, masses, XYZs, RPYs. Especially when, but not limited to, using parts from any vendor’s “erector set”.

This is to ease the ROS learning curve but could also be a way for vendors to deliver pre-built URDF assemblies. It is an extension to xacro that has no side effect on existing operation or behavior. I would like to get feedback and ideas on the proposed solution I am working on.

I propose we add a few extension functions/macros that can simplify the <link> and <joint> blocks for robot kits. To distill it down to a minimum, these extensions are a way to load and configure URDF xml fragments from remote repositories. I use vendor loosely. You can load parts remotely from any publisher on git-hub or http URI or design your own local part repo.

We start with a fragment something like this in our xacro/URDF to define where our external resources are:

   	<repository name="erector" src="http://robots-r-us.com/ros2/parts" />
   	<repository name="lidar" src="git://<git-url>" />
  	<repository name="mystuff" src="package://my_package/myparts" />

Edit: On second thought, scratch downloading via http and git…in the spirit of ROS a repo is just resource files in a normal ROS package.
Each repo is a part DB. Each part has a name, STL/DAE url, inertia data and most importantly a list of named attachment points. Each attachment point has related transform and type info (fixed, rotational, linear, axis). Parts are URDF fragments so may also include other stuff like gazebo or ros2-controls fragments. Now we can build robots using simpler xml referring to these remote part blocks by their repo name and sku:

    <part sku="erector:torso-1" link="base_link">
    	-- loads torso-1 part# from 'erector' repo
    	-- no attachment point specified here
    	-- optionally add more xml that goes into the output URDF
    	<more xml content for link node ...>
    </part>

    <!-- these parts attach to a parent using a pre-defined attachment point by name
            (attachment points defined in vendor part description) -->
    <part
        sku="erector:BA101"
        link="left-shoulder"
        parent="base_link"
        attachment="A" />
    <part
        sku="erector:Servo_HT1"
        link="left-shoulder-servo"
        parent="left-shoulder"
        attachment="Horn1"
      <!-- arguments passed into part template just like xacro:macro -->
        min="-1.5"
        max="1.5"
        />
    <part
        sku="erector:BA104B"
        link="humerus"
        parent="left-shoulder-servo"
        attachment="C" />
    <part
        sku="erector:Servo_HT1"
        link="left-humerus-servo"
        parent="humerus"
        attachment="Horn1"
        min="-1.5"
        max="1.5"
        />
    <part
        sku="erector:BA101"
        link="radius"
        parent="left-humerus-servo"
        attachment="B" />

The ‘parent’ and ‘attachment’ attributes translate into a <joint> and the rest into <link>. Attachment points are unique to each part and defined in the vendor part file. User can still define their own or custom transform if a pre-defined attachment point doesn’t exist.

I could make this a standalone tool but xacro already has a useful set of processing macros/functions and I think this feature really fits into the purpose of xacro.

A part is basically a xacro macro, only it is in an external file. The work here is in the download/cache management of the the repo sources, and the repo is then an include file of defined part macros. Second, there is some work to support the “attachment” directives.

It’s entirely possible some robots could be created from “erector sets” that need no coordinates, inertia, hysics or even custom STL/DAE required. For new users this could be a big hurdle taken care of. Servos, erector set hardware, Lidars, IMUs and other predefined URDF blocks can be imported where the complicated stuff is pre-defined. I certainly had a high learning curve/barrier getting to know URDF, colcon, ros2-cli, launch files and a buggy Solidworks plugin (which I am still grateful to have). Fortunately, I got over the hump and love Ros2 and eventually rewrote my own URDF with xacro but I can see how new users will struggle. I and a few others would like to make the barrier a bit easier.

Any effect to current Xacro users?
No, this feature should be optional and cause no side effects to existing xacro files. Only if a <repositories> block exists in the URDF would external data and/or part DBs be downloaded and placed on the user’s hard drive. I’m not sure where the local repo cache would go (suggestions?). The user would be responsible for vetting a vendor’s part files. Perhaps at some point a part catalog web site might exist to help users discover parts.

Thoughts?

2 Likes

Edit: To be more ROS standard, the repo will just be a collection of xacro, yml and STL files wrapped up in a standard ROS package. This means we don’t have to handle repository cache directories, different versions and all that mess…instead a parts repo is managed like any other ROS package and part of the ament index. This also means <repository> tag is mostly just the xacro include function. The scope of work is reduced.