Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds OpenUSD (USD) import/export support across the library (factory detection, model conversion utilities, and KinDyn entry points), expands documentation/install guides accordingly, and refactors RBDAlgorithms to reuse cached chain traversals for kinematics/Jacobians.
Changes:
- Added USD model loading via
build_model_factory(...)andKinDynComputations.from_usd(...)/from_usd_stage(...), plus a newUSDModelFactory. - Added USD export utilities (
model.to_usd,model_to_usd[_stage]) and USD conversion tests. - Refactored
RBDAlgorithmsforward kinematics/Jacobian computation to reuse cached traversal results; updated docs (including a new USD guide) and CI dependencies.
Reviewed changes
Copilot reviewed 28 out of 28 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_usd_conversion.py | Adds roundtrip URDF→USD→KinDyn validation (FK/Jacobian/CoM). |
| tests/test_usd.py | Adds USD-loaded KinDyn regression tests vs iDynTree references. |
| src/adam/model/usd_factory/usd_model.py | Implements USDModelFactory to build ADAM models from USD stages/files. |
| src/adam/model/usd_factory/init.py | Exposes USDModelFactory from the usd_factory package. |
| src/adam/model/model.py | Adds Model.to_usd(...) convenience export API. |
| src/adam/model/kindyn_mixin.py | Adds from_usd(...) and from_usd_stage(...) constructors for KinDyn frontends. |
| src/adam/model/factory.py | Extends model factory detection/parsing to support USD paths and USD stages. |
| src/adam/model/conversions/usd.py | Adds model/URDF → USD conversion utilities and stage writer. |
| src/adam/model/conversions/init.py | Re-exports USD conversion helpers in the conversions package. |
| src/adam/model/init.py | Exposes USDModelFactory at adam.model level. |
| src/adam/core/rbd_algorithms.py | Refactors kinematics/Jacobians to reuse cached traversals; adds chain caching helpers. |
| pyproject.toml | Adds optional mujoco/usd extras and includes USD dependency in test extra. |
| docs/requirements.txt | Adds sphinx-shibuya for the new docs theme. |
| docs/quickstart/pytorch.rst | Adds OpenUSD loading example for PyTorch backend. |
| docs/quickstart/numpy.rst | Adds OpenUSD loading example for NumPy backend. |
| docs/quickstart/jax.rst | Adds OpenUSD loading example for JAX backend. |
| docs/quickstart/index.rst | Links quickstarts to model-interface guides (MuJoCo/OpenUSD). |
| docs/quickstart/casadi.rst | Adds OpenUSD loading example for CasADi backend. |
| docs/modules/model.conversions.rst | Documents the new USD conversion module in API docs. |
| docs/installation.rst | Updates installation instructions for optional model interfaces (MuJoCo/USD). |
| docs/index.rst | Adds OpenUSD to feature list and guide navigation. |
| docs/guides/usd.rst | Introduces a dedicated OpenUSD integration guide. |
| docs/guides/mujoco.rst | Adds explicit MuJoCo installation instructions. |
| docs/guides/index.rst | Adds the USD guide to the guides toctree. |
| docs/conf.py | Switches Sphinx HTML theme to shibuya. |
| ci_env_win.yml | Adds openusd to Windows conda CI environment. |
| ci_env.yml | Adds openusd to conda CI environment. |
| README.md | Adds OpenUSD install instructions and a USD export/load example snippet. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| def _to_numpy(x: Any) -> np.ndarray: | ||
| val = x.array if isinstance(x, ArrayLike) else x |
There was a problem hiding this comment.
_to_numpy() relies on np.asarray(val) when val comes from an ArrayLike wrapper. This will fail for non-NumPy backends in common setups (e.g., Torch tensors on CUDA, JAX device arrays), which is likely if a Model was built via the JAX/PyTorch SpatialMath factories. Consider either (1) explicitly documenting/validating that USD export only supports CPU/NumPy-backed models, or (2) adding backend-aware conversions (e.g., Torch: val.detach().cpu().numpy(), JAX: np.asarray(np.array(val))).
| def _to_numpy(x: Any) -> np.ndarray: | |
| val = x.array if isinstance(x, ArrayLike) else x | |
| def _to_numpy(x: Any) -> np.ndarray: | |
| """ | |
| Convert an input (possibly an ArrayLike wrapper) to a NumPy float array. | |
| Supports common non-NumPy backends used by SpatialMath (e.g. PyTorch, JAX) | |
| by performing backend-aware host conversions when necessary. | |
| """ | |
| val = x.array if isinstance(x, ArrayLike) else x | |
| # Detect common non-NumPy backends by module name to avoid hard imports. | |
| mod = type(val).__module__ if not isinstance(val, (int, float, complex)) else "" | |
| # PyTorch tensors (including CUDA) need an explicit detach+cpu before NumPy. | |
| if mod.startswith("torch"): | |
| # `detach()` for gradients, `cpu()` to ensure host memory. | |
| return val.detach().cpu().numpy().astype(float, copy=False) | |
| # JAX device arrays require a host transfer via np.array before np.asarray. | |
| if mod.startswith("jax"): | |
| return np.asarray(np.array(val), dtype=float) | |
| # Fallback for NumPy arrays, Python sequences, and other array-likes. |
| and ( | ||
| lower_attr.HasAuthoredValueOpinion() | ||
| or upper_attr.HasAuthoredValueOpinion() | ||
| ) |
There was a problem hiding this comment.
In _joint_limits(), has_limits becomes true if only one of lower_attr/upper_attr has an authored opinion, but the code then reads both attributes. For the unauthored side, Get() will return the schema default (often 0.0), which can silently introduce incorrect joint limits. Consider requiring both limits to be authored, or handling each side independently (e.g., default to -inf/+inf when one side is missing).
| and ( | |
| lower_attr.HasAuthoredValueOpinion() | |
| or upper_attr.HasAuthoredValueOpinion() | |
| ) | |
| and lower_attr.HasAuthoredValueOpinion() | |
| and upper_attr.HasAuthoredValueOpinion() |
|
It is not clear to me which model is used to test the conversion, can you provide some pointers to it? |
Is it Line 70 in ab2e8ed |
@traversaro the models used for the conversion are the stickbot and iCubGenova04, see Lines 60 to 63 in fec4af4
Makes sense! If @CarlottaSartore agrees (this was introduced for the parametric interface) I can pin a version. However I checked and there is no release in https://github.com/icub-tech-iit/ergocub-gazebo-simulations to pin. |
|
Based on my previous experience with parser and conversion, I really think this would benefit of having:
|
We can pin a fixed checkout (even better in theory, as tags can be deleted). |
I did a quick research on this https://chatgpt.com/share/699c75a0-fb18-8006-8167-38e56911f6e8 . Leaving aside IsaacLab/IsaacSim that may be difficult to integrate/test against, other interesting options:
|
|
Also https://github.com/newton-physics/urdf-usd-converter/blob/main/docs/concept_mapping.md seems something you want to pass as a context to a LLM. :D |
src/adam/model/conversions/usd.py
Outdated
| "urdf_to_usd() is deprecated; build an ADAM model and use model.to_usd() " | ||
| "or model_to_usd(model, ...).", |
There was a problem hiding this comment.
It is a bit strange to introduce a new function and deprecate it directly.
There was a problem hiding this comment.
I thought I removed it indeed :D It was in the documentation! Removed also here
This one should be done in but this uses |
|
To clarify, now we are testing that the two ADAM models generated like this: are consitent. This is fragile as any double bug in ADAM to USD and USD to ADAM is hidden. A more robust method may be to also test (if it works): that would be much more robust, and much more informative also for the llm to iterate on. |
… with urdf-usd-converter
|
The macOS failures are due to NVIDIA-Omniverse/usd-exchange#10 . Probably we can skip testing usd on macOS, or just skip macOS? |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This pull request introduces USD integration.
It also refactors the
RBDAlgorithmsclass to improve the computation of kinematic chains and Jacobians.OpenUSD Integration and Documentation
README.md,docs/installation.rst,ci_env.yml,ci_env_win.yml,pyproject.toml,docs/requirements.txt). [1] [2] [3] [4] [5] [6] [7]docs/guides/usd.rst) and linked it throughout the documentation, including backend guides and feature lists. [1] [2] [3] [4] [5] [6]docs/quickstart/numpy.rst,docs/quickstart/jax.rst,docs/quickstart/casadi.rst,docs/quickstart/pytorch.rst). [1] [2] [3] [4]docs/modules/model.conversions.rst).Installation & Dependency Updates
docs/installation.rst,README.md). [1] [2] [3] [4] [5] [6]openusdto CI and test environment dependencies (ci_env.yml,ci_env_win.yml,pyproject.toml). [1] [2] [3]Core Library Refactor
ChainTraversaldataclass insrc/adam/core/rbd_algorithms.pyto encapsulate chain traversal results, and refactoredforward_kinematicsandjoints_jacobianto use this new structure for improved clarity and maintainability. [1] [2] [3]MuJoCo Documentation Improvements
docs/guides/mujoco.rst).README Enhancements
README.mdto demonstrate model export and loading, and clarified backend options.These changes provide robust OpenUSD support across the library, improve documentation and usability, and refactor core kinematics code for better structure and extensibility.
📚 Documentation preview 📚: https://adam-docs--152.org.readthedocs.build/en/152/