Discuss: Tools and Best Practices for 3D Robot Assets (URDF, SDFormat, CAD, etc)

In our system, the single source of truth is a collection of Xacro files. We have a separate robot_description package that contains the basic model for RViz, laser filtering and similar use-cases, and then we have robot_gazebo package which adds simulation-related things (by specifying a new top-level xacro file that includes the _description xacro). Each sensor/removable part provides its own xacro that is conditionally included in the final Xacro.

Everything is generated on the fly when the nodes are starting and is configured by a hierarchical collection of YAML configs (similar to what some people described in Handle unique parameters for robot instances ). The fused YAML is passed both as parameters to the Xacro renderer and is also pushed to roscore as parameters so that other nodes can access these values later.

One of the parameters the Xacro received is also rendering_target, which can have values urdf, sdf-classic or sdf, which allows us to specify parts of the models that only make sense when you render the model for Rviz, Gazebo Classic or new Gazebo. For example, closing of kinematic loops can be done so that you just omit the last link in urdf target, but add it in sdf. We even have further parameters that tell the pipeline e.g. that the model will be used for laser filtering, so that it can inflate the links accordingly. Other parameters specify presence and calibration of various sensors, which we change a lot.

The pipeline the runs (simplified a lot) cat robot_model.xacro | print_robot_urdf | print_robot_sdf where print_robot_urdf is a script responsible for collecting and fusing the YAML configs, pushing them to param server and converting them to Xacro args, and then calling xacro on the correct .xacro file. print_robot_sdf is basically gz sdf that gets the URDF with <gazebo> tags on input and outputs the SDF file.

A large part of our pipeline was used in our SubT models: subt/submitted_models/ctu_cras_norlab_absolem_sensor_config_1 at master · osrf/subt · GitHub (directories config, scripts and urdf).

Over time, we’ve noticed some downsides:

  1. When adding a new sensor, you have to add it at multiple places (_description, _gazebo, configs) and it’s not easy to maintain consistency.
  2. The YAML params cannot be easily passed to roslaunch, so that it’s not possible to have a single file configuring which sensors are on the robot that would both define the model and also the drivers to launch. We hope this limitation will not apply when we switch to ROS 2.

But the pros are great for us:

  1. Fully and dynamically configurable robot model (we even have GitHub - peci1/dynamic_robot_state_publisher: Improved ROS robot_state_publisher which can update the robot model via dynamic_reconfigure. that allows reloading the model on-the-fly and notifying compatible nodes).
  2. We also have a dynamic_reconfigure for all model YAML params which allows us to interactively play with the model while the driver is running.
  3. The model is consistent between simulation, laser filtering, RViz etc.
  4. It allows fine-tuning the model for each of the “outputs” - e.g. solid color rendering works differently in rviz and new Gazebo, so we can have a different color for a link for Rviz presentation and for Gazebo presentation.
  5. As we automatically save all params when recording a bag, both the final robot model and the parameters it was rendered from are available at a later point.
  6. This means the model can be re-assembled with different configs later. If you e.g. figure out you had a wrongly calibrated part on the robot when recording data, you can fix the calibration later, overwrite the recorded params file and regenerate the model.