Source code for omni.isaac.lab.sim.converters.urdf_converter

# Copyright (c) 2022-2024, The Isaac Lab Project Developers.
# All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause

from __future__ import annotations

import os

import omni.kit.commands
import omni.usd
from omni.isaac.core.utils.extensions import enable_extension
from omni.isaac.version import get_version
from pxr import Usd

from .asset_converter_base import AssetConverterBase
from .urdf_converter_cfg import UrdfConverterCfg

_DRIVE_TYPE = {
    "none": 0,
    "position": 1,
    "velocity": 2,
}
"""Mapping from drive type name to URDF importer drive number."""

_NORMALS_DIVISION = {
    "catmullClark": 0,
    "loop": 1,
    "bilinear": 2,
    "none": 3,
}
"""Mapping from normals division name to urdf importer normals division number."""


[docs]class UrdfConverter(AssetConverterBase): """Converter for a URDF description file to a USD file. This class wraps around the `omni.isaac.urdf_importer`_ extension to provide a lazy implementation for URDF to USD conversion. It stores the output USD file in an instanceable format since that is what is typically used in all learning related applications. .. caution:: The current lazy conversion implementation does not automatically trigger USD generation if only the mesh files used by the URDF are modified. To force generation, either set :obj:`AssetConverterBaseCfg.force_usd_conversion` to True or delete the output directory. .. note:: From Isaac Sim 2023.1 onwards, the extension name changed from ``omni.isaac.urdf`` to ``omni.importer.urdf``. This converter class automatically detects the version of Isaac Sim and uses the appropriate extension. The new extension supports a custom XML tag``"dont_collapse"`` for joints. Setting this parameter to true in the URDF joint tag prevents the child link from collapsing when the associated joint type is "fixed". .. _omni.isaac.urdf_importer: https://docs.omniverse.nvidia.com/isaacsim/latest/ext_omni_isaac_urdf.html """ cfg: UrdfConverterCfg """The configuration instance for URDF to USD conversion."""
[docs] def __init__(self, cfg: UrdfConverterCfg): """Initializes the class. Args: cfg: The configuration instance for URDF to USD conversion. """ super().__init__(cfg=cfg)
""" Implementation specific methods. """ def _convert_asset(self, cfg: UrdfConverterCfg): """Calls underlying Omniverse command to convert URDF to USD. Args: cfg: The URDF conversion configuration. """ import_config = self._get_urdf_import_config(cfg) omni.kit.commands.execute( "URDFParseAndImportFile", urdf_path=cfg.asset_path, import_config=import_config, dest_path=self.usd_path, ) # fix the issue that material paths are not relative if self.cfg.make_instanceable: instanced_usd_path = os.path.join(self.usd_dir, self.usd_instanceable_meshes_path) stage = Usd.Stage.Open(instanced_usd_path) # resolve all paths relative to layer path source_layer = stage.GetRootLayer() omni.usd.resolve_paths(source_layer.identifier, source_layer.identifier) stage.Save() # fix the issue that material paths are not relative # note: This issue seems to have popped up in Isaac Sim 2023.1.1 stage = Usd.Stage.Open(self.usd_path) # resolve all paths relative to layer path source_layer = stage.GetRootLayer() omni.usd.resolve_paths(source_layer.identifier, source_layer.identifier) stage.Save() """ Helper methods. """ def _get_urdf_import_config(self, cfg: UrdfConverterCfg) -> omni.importer.urdf.ImportConfig: """Create and fill URDF ImportConfig with desired settings Args: cfg: The URDF conversion configuration. Returns: The constructed ``ImportConfig`` object containing the desired settings. """ # Enable urdf extension enable_extension("omni.importer.urdf") from omni.importer.urdf import _urdf as omni_urdf import_config = omni_urdf.ImportConfig() # set the unit scaling factor, 1.0 means meters, 100.0 means cm import_config.set_distance_scale(1.0) # set imported robot as default prim import_config.set_make_default_prim(True) # add a physics scene to the stage on import if none exists import_config.set_create_physics_scene(False) # -- instancing settings # meshes will be placed in a separate usd file import_config.set_make_instanceable(cfg.make_instanceable) import_config.set_instanceable_usd_path(self.usd_instanceable_meshes_path) # -- asset settings # default density used for links, use 0 to auto-compute import_config.set_density(cfg.link_density) # import inertia tensor from urdf, if it is not specified in urdf it will import as identity import_config.set_import_inertia_tensor(cfg.import_inertia_tensor) # decompose a convex mesh into smaller pieces for a closer fit import_config.set_convex_decomp(cfg.convex_decompose_mesh) import_config.set_subdivision_scheme(_NORMALS_DIVISION["bilinear"]) # -- physics settings # create fix joint for base link import_config.set_fix_base(cfg.fix_base) # consolidating links that are connected by fixed joints import_config.set_merge_fixed_joints(cfg.merge_fixed_joints) # self collisions between links in the articulation import_config.set_self_collision(cfg.self_collision) # default drive type used for joints import_config.set_default_drive_type(_DRIVE_TYPE[cfg.default_drive_type]) # default proportional gains import_config.set_default_drive_strength(cfg.default_drive_stiffness) # default derivative gains import_config.set_default_position_drive_damping(cfg.default_drive_damping) if get_version()[2] == "4": # override joint dynamics parsed from urdf import_config.set_override_joint_dynamics(cfg.override_joint_dynamics) return import_config