diff --git a/.github/workflows/read_the_docs.yml b/.github/workflows/read_the_docs.yml new file mode 100644 index 0000000..a5e83ac --- /dev/null +++ b/.github/workflows/read_the_docs.yml @@ -0,0 +1,20 @@ +name: Read the Docs +on: + pull_request_target: + types: + - opened + # Execute this action only on PRs that touch + # documentation files. + # paths: + # - "docs/**" + +permissions: + pull-requests: write + +jobs: + documentation-links: + runs-on: ubuntu-latest + steps: + - uses: readthedocs/actions/preview@v1 + with: + project-slug: "adam-docs" diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..f0fa032 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,37 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.12" + # You can also specify other tool versions: + # nodejs: "20" + # rust: "1.70" + # golang: "1.20" + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs + # builder: "dirhtml" + # Fail on all warnings to avoid broken references + # fail_on_warning: true + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: +# - pdf +# - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: docs/requirements.txt + +formats: all diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..ed88099 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/_templates/custom-class-template.rst b/docs/_templates/custom-class-template.rst new file mode 100644 index 0000000..d2718c5 --- /dev/null +++ b/docs/_templates/custom-class-template.rst @@ -0,0 +1,33 @@ +{{ fullname | escape | underline}} + +.. currentmodule:: {{ module }} + +.. autoclass:: {{ objname }} + :members: + :show-inheritance: + :private-members: + :undoc-members: + + {% block methods %} + .. automethod:: __init__ + + {% if methods %} + .. rubric:: {{ _('Methods') }} + + .. autosummary:: + {% for item in methods %} + ~{{ name }}.{{ item }} + {%- endfor %} + {% endif %} + {% endblock %} + + {% block attributes %} + {% if attributes %} + .. rubric:: {{ _('Attributes') }} + + .. autosummary:: + {% for item in attributes %} + ~{{ name }}.{{ item }} + {%- endfor %} + {% endif %} + {% endblock %} \ No newline at end of file diff --git a/docs/_templates/custom-module-template.rst b/docs/_templates/custom-module-template.rst new file mode 100644 index 0000000..1323800 --- /dev/null +++ b/docs/_templates/custom-module-template.rst @@ -0,0 +1,75 @@ +{{ fullname | escape | underline}} + +.. automodule:: {{ fullname }} + + {% block attributes %} + {% if attributes %} + .. rubric:: Module Attributes + + .. autosummary:: + :toctree: + {% for item in attributes %} + {{ item }} + {%- endfor %} + {% endif %} + {% endblock %} + + {% block classes %} + {% if classes %} + .. rubric:: {{ _('Classes') }} + + .. autosummary:: + :toctree: + :template: custom-class-template.rst + {% for item in classes %} + {{ item }} + {%- endfor %} + {% endif %} + {% endblock %} + + {% block inheritance %} + {% if classes %} + + .. inheritance-diagram:: {{ fullname }} + :caption: Inheritance Relationship + :parts: -1 + {% endif %} + {% endblock %} + + {% block functions %} + {% if functions %} + .. rubric:: {{ _('Functions') }} + + .. autosummary:: + :toctree: + {% for item in functions %} + {{ item }} + {%- endfor %} + {% endif %} + {% endblock %} + + {% block exceptions %} + {% if exceptions %} + .. rubric:: {{ _('Exceptions') }} + + .. autosummary:: + :toctree: + {% for item in exceptions %} + {{ item }} + {%- endfor %} + {% endif %} + {% endblock %} + +{% block modules %} +{% if modules %} +.. rubric:: Modules + +.. autosummary:: + :toctree: + :template: custom-module-template.rst + :recursive: +{% for item in modules %} + {{ item }} +{%- endfor %} +{% endif %} +{% endblock %} \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..c64063f --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,82 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +import os +import subprocess +import sys + +import adam + +sys.path.insert(0, os.path.abspath(".")) +sys.path.insert(0, os.path.abspath("../")) +sys.path.insert(0, os.path.abspath("../../")) +sys.path.insert(0, os.path.abspath("../src/")) + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = "adam" +copyright = "2021, Artificial and Mechanical Intelligence Lab" +author = "Artificial and Mechanical Intelligence Lab" +# get release from git tag + +release = ( + subprocess.check_output(["git", "describe", "--tags", "--always"]).decode().strip() +) + + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + "sphinx.ext.duration", + "sphinx.ext.doctest", + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + # "sphinx.ext.inheritance_diagram", + "sphinx.ext.napoleon", + "sphinx.ext.viewcode", + # "sphinx.ext.autosectionlabel", + "sphinx_copybutton", + "myst_parser", + "sphinx.ext.napoleon", + "autoapi.extension", +] + +autoapi_dirs = ["../src/"] + +source_suffix = { + ".rst": "restructuredtext", + ".txt": "markdown", + ".md": "markdown", +} + +autosummary_generate = True +autodoc_member_order = "bysource" + +templates_path = ["_templates"] +exclude_patterns = [] + +html_title = f"adam" + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = "sphinx_book_theme" +# html_theme = "sphinx_rtd_theme" + +# html_theme = "furo" +# html_logo = "pirati.png" + +html_context = { + "display_github": True, + "github_user": "TOB-KNPOB", + "github_repo": "Jabref2Obsdian", + "github_version": "main", + "conf_py_path": "/docs/", +} + +html_static_path = ["_static"] diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..e0a63d3 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,51 @@ +.. adam documentation master file, created by + sphinx-quickstart on Fri Jun 28 14:10:15 2024. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + + +adam +---- + +**Automatic Differentiation for rigid-body-dynamics AlgorithMs** + +**adam** implements a collection of algorithms for calculating rigid-body dynamics for **floating-base** robots, in mixed and body fixed representations using: + +.. create rst list with links to the following libraries + +- `Jax `_ +- `CasADi `_ +- `PyTorch `_ +- `NumPy `_ + + +**adam** employs the automatic differentiation capabilities of these frameworks to compute, if needed, gradients, Jacobian, Hessians of rigid-body dynamics quantities. This approach enables the design of optimal control and reinforcement learning strategies in robotics. +Thanks to the `jax.vmap`-ing and `jax.jit`-ing capabilities, the algorithms can be run on batches of inputs, which are possibly converted to PyTorch using the `jax2torch` conversion functions. + + +**adam** is based on **Roy Featherstone's Rigid Body Dynamics Algorithms**. + +Examples +-------- + +Have a look at the examples `folder in the repository `_! + + +License +------- + +`BSD-3-Clause `_ + + +.. toctree:: + :maxdepth: 2 + :caption: Getting started: + + installation + quickstart/index + +.. toctree:: + :maxdepth: 2 + :caption: API: + + modules/index diff --git a/docs/installation.rst b/docs/installation.rst new file mode 100644 index 0000000..48fbf46 --- /dev/null +++ b/docs/installation.rst @@ -0,0 +1,34 @@ +Installation +============ +This is the installation guide for the project. + + +Prerequisites +------------- + +adam requires python 3.7 or later. + + +🐍 Conda installation +--------------------- + +We suggest to install adam using `conda `_: + +.. code-block:: bash + + conda install adam-robotics -c conda-forge + +📦 Pip installation +-------------------- + +You can also install adam using `pip `_: + +.. code-block:: bash + + pip install adam-robotics + +If you want to install all the dependencies install ``adam-robotics[all]``. + +.. note:: + + If the GPU support for ``JAX`` is needed, follow the instructions in the `Jax documentation `_. diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..747ffb7 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/modules/adam.geometry.rst b/docs/modules/adam.geometry.rst new file mode 100644 index 0000000..9c140d3 --- /dev/null +++ b/docs/modules/adam.geometry.rst @@ -0,0 +1,21 @@ +adam.geometry package +===================== + +Submodules +---------- + +adam.geometry.utils module +-------------------------- + +.. automodule:: adam.geometry.utils + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: adam.geometry + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/modules/adam.model.std_factories.rst b/docs/modules/adam.model.std_factories.rst new file mode 100644 index 0000000..c0f2b52 --- /dev/null +++ b/docs/modules/adam.model.std_factories.rst @@ -0,0 +1,29 @@ +adam.model.std\_factories package +================================= + +Submodules +---------- + +adam.model.std\_factories.std\_joint module +------------------------------------------- + +.. automodule:: adam.model.std_factories.std_joint + :members: + :undoc-members: + :show-inheritance: + +adam.model.std\_factories.std\_link module +------------------------------------------ + +.. automodule:: adam.model.std_factories.std_link + :members: + :undoc-members: + :show-inheritance: + +adam.model.std\_factories.std\_model module +------------------------------------------- + +.. automodule:: adam.model.std_factories.std_model + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/modules/adam.parametric.casadi.rst b/docs/modules/adam.parametric.casadi.rst new file mode 100644 index 0000000..153b30b --- /dev/null +++ b/docs/modules/adam.parametric.casadi.rst @@ -0,0 +1,13 @@ +adam.parametric.casadi package +============================== + +Submodules +---------- + +adam.parametric.casadi.computations\_parametric module +------------------------------------------------------ + +.. automodule:: adam.parametric.casadi.computations_parametric + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/modules/adam.parametric.jax.rst b/docs/modules/adam.parametric.jax.rst new file mode 100644 index 0000000..f24c5ef --- /dev/null +++ b/docs/modules/adam.parametric.jax.rst @@ -0,0 +1,13 @@ +adam.parametric.jax package +=========================== + +Submodules +---------- + +adam.parametric.jax.computations\_parametric module +--------------------------------------------------- + +.. automodule:: adam.parametric.jax.computations_parametric + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/modules/adam.parametric.model.parametric_factories.rst b/docs/modules/adam.parametric.model.parametric_factories.rst new file mode 100644 index 0000000..f1643c9 --- /dev/null +++ b/docs/modules/adam.parametric.model.parametric_factories.rst @@ -0,0 +1,29 @@ +adam.parametric.model.parametric\_factories package +=================================================== + +Submodules +---------- + +adam.parametric.model.parametric\_factories.parametric\_joint module +-------------------------------------------------------------------- + +.. automodule:: adam.parametric.model.parametric_factories.parametric_joint + :members: + :undoc-members: + :show-inheritance: + +adam.parametric.model.parametric\_factories.parametric\_link module +------------------------------------------------------------------- + +.. automodule:: adam.parametric.model.parametric_factories.parametric_link + :members: + :undoc-members: + :show-inheritance: + +adam.parametric.model.parametric\_factories.parametric\_model module +-------------------------------------------------------------------- + +.. automodule:: adam.parametric.model.parametric_factories.parametric_model + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/modules/adam.parametric.model.rst b/docs/modules/adam.parametric.model.rst new file mode 100644 index 0000000..dcf6e3e --- /dev/null +++ b/docs/modules/adam.parametric.model.rst @@ -0,0 +1,10 @@ +adam.parametric.model package +============================= + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + adam.parametric.model.parametric_factories diff --git a/docs/modules/adam.parametric.numpy.rst b/docs/modules/adam.parametric.numpy.rst new file mode 100644 index 0000000..9e996a2 --- /dev/null +++ b/docs/modules/adam.parametric.numpy.rst @@ -0,0 +1,13 @@ +adam.parametric.numpy package +============================= + +Submodules +---------- + +adam.parametric.numpy.computations\_parametric module +----------------------------------------------------- + +.. automodule:: adam.parametric.numpy.computations_parametric + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/modules/adam.parametric.pytorch.rst b/docs/modules/adam.parametric.pytorch.rst new file mode 100644 index 0000000..de8d2aa --- /dev/null +++ b/docs/modules/adam.parametric.pytorch.rst @@ -0,0 +1,13 @@ +adam.parametric.pytorch package +=============================== + +Submodules +---------- + +adam.parametric.pytorch.computations\_parametric module +------------------------------------------------------- + +.. automodule:: adam.parametric.pytorch.computations_parametric + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/modules/adam.parametric.rst b/docs/modules/adam.parametric.rst new file mode 100644 index 0000000..43ece6f --- /dev/null +++ b/docs/modules/adam.parametric.rst @@ -0,0 +1,24 @@ +Parametric package +======================= + +This package provides an interface for parametric models. + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + adam.parametric.casadi + adam.parametric.jax + adam.parametric.model + adam.parametric.numpy + adam.parametric.pytorch + +Module contents +--------------- + +.. automodule:: adam.parametric + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/modules/casadi.rst b/docs/modules/casadi.rst new file mode 100644 index 0000000..fcb2d00 --- /dev/null +++ b/docs/modules/casadi.rst @@ -0,0 +1,13 @@ +CasADi interface +=================== + +This module provides an interface to CasADi, a symbolic framework for automatic differentiation and optimization. + +---------------- + +.. currentmodule:: adam.casadi + +.. automodule:: adam.casadi.computations + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/modules/index.rst b/docs/modules/index.rst new file mode 100644 index 0000000..8892a31 --- /dev/null +++ b/docs/modules/index.rst @@ -0,0 +1,18 @@ +Modules +========== + +This section contains the documentation for the different modules of the library. + +.. _modules: + +.. toctree:: + :maxdepth: 2 + + casadi + jax + pytorch + pytorch_batched + numpy + model + model.conversions + adam.parametric diff --git a/docs/modules/jax.rst b/docs/modules/jax.rst new file mode 100644 index 0000000..2aeb700 --- /dev/null +++ b/docs/modules/jax.rst @@ -0,0 +1,30 @@ +Jax inteface +================ + +This module provides the Jax implementation of the Rigid Body Dynamics algorithms. + +.. tip:: + + We suggest to ``jax.jit`` the functions as it will make them run faster! + +.. tip:: + + The functions in this module can be also ``jax.vmap``-ed to run on batches of inputs. + +.. note:: + + The first time you run a ``jax.jit``-ed function, it will take a bit longer to execute as they are being compiled by Jax. + +.. note:: + + If the GPU support for ``JAX`` is needed, follow the instructions in the `Jax documentation `_. + + +---------------- + +.. currentmodule:: adam.jax + +.. automodule:: adam.jax.computations + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/modules/model.conversions.rst b/docs/modules/model.conversions.rst new file mode 100644 index 0000000..7e7f825 --- /dev/null +++ b/docs/modules/model.conversions.rst @@ -0,0 +1,10 @@ +Model conversions +============================== + +.. currentmodule:: adam.model.conversions + + +.. automodule:: adam.model.conversions.idyntree + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/modules/model.rst b/docs/modules/model.rst new file mode 100644 index 0000000..003a709 --- /dev/null +++ b/docs/modules/model.rst @@ -0,0 +1,27 @@ +Model package +================== + +The model package builds the graph of the robot model and stores the information about the robot's kinematics and dynamics. + +.. currentmodule:: adam.model + +.. automodule:: adam.model.model + :members: + :undoc-members: + :show-inheritance: + +adam.model.tree module +---------------------- + +.. automodule:: adam.model.tree + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: adam.model + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/modules/numpy.rst b/docs/modules/numpy.rst new file mode 100644 index 0000000..e4fe2de --- /dev/null +++ b/docs/modules/numpy.rst @@ -0,0 +1,13 @@ +NumPy +================== + +This module provides the NumPy implementation of the Rigid Body Dynamics algorithms. + +---------------- + +.. currentmodule:: adam.numpy + +.. automodule:: adam.numpy.computations + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/modules/pytorch.rst b/docs/modules/pytorch.rst new file mode 100644 index 0000000..4870c48 --- /dev/null +++ b/docs/modules/pytorch.rst @@ -0,0 +1,17 @@ +PyTorch interface +==================== + +This module provides the PyTorch implementation of the Rigid Body Dynamics algorithms. + +.. tip:: + + For the batched version of the algorithms, see :mod:`adam.pytorch.computation_batch`. + +---------------- + +.. currentmodule:: adam.pytorch + +.. automodule:: adam.pytorch.computations + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/modules/pytorch_batched.rst b/docs/modules/pytorch_batched.rst new file mode 100644 index 0000000..1e5001e --- /dev/null +++ b/docs/modules/pytorch_batched.rst @@ -0,0 +1,24 @@ +PyTorch Batched interface +========================= + +This module implements the batched version of the Rigid Body Dynamics algorithms using PyTorch. +This module uses Jax under the hood, then the functions are ``jax.vmap``-ed and ``jax.jit``-ed to run on batches of inputs, which are ultimately converted to PyTorch using the ``jax2torch`` conversion functions. + +.. note:: + + The first time you run a function from this module, it will take a bit longer to execute as they are being compiled by Jax. + + +.. note:: + + If the GPU support for ``JAX`` is needed, follow the instructions in the `Jax documentation `_. + + +---------------- + +.. currentmodule:: adam.pytorch.computation_batch + +.. automodule:: adam.pytorch.computation_batch + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/quickstart/casadi.rst b/docs/quickstart/casadi.rst new file mode 100644 index 0000000..1f089a9 --- /dev/null +++ b/docs/quickstart/casadi.rst @@ -0,0 +1,47 @@ +CasADi usage +============ + +The following example shows how to call an instance of the ``adam.casadi.KinDynComputations`` class and use it to compute the mass matrix and forward dynamics of a floating-base robot. + +.. code-block:: python + + import adam + from adam.casadi import KinDynComputations + import icub_models + import numpy as np + + # if you want to icub-models https://github.com/robotology/icub-models to retrieve the urdf + model_path = icub_models.get_model_file("iCubGazeboV2_5") + # The joint list + joints_name_list = [ + 'torso_pitch', 'torso_roll', 'torso_yaw', 'l_shoulder_pitch', + 'l_shoulder_roll', 'l_shoulder_yaw', 'l_elbow', 'r_shoulder_pitch', + 'r_shoulder_roll', 'r_shoulder_yaw', 'r_elbow', 'l_hip_pitch', 'l_hip_roll', + 'l_hip_yaw', 'l_knee', 'l_ankle_pitch', 'l_ankle_roll', 'r_hip_pitch', + 'r_hip_roll', 'r_hip_yaw', 'r_knee', 'r_ankle_pitch', 'r_ankle_roll' + ] + + kinDyn = KinDynComputations(model_path, joints_name_list) + # choose the representation you want to use the body fixed representation + kinDyn.set_frame_velocity_representation(adam.Representations.BODY_FIXED_REPRESENTATION) + # or, if you want to use the mixed representation (that is the default) + kinDyn.set_frame_velocity_representation(adam.Representations.MIXED_REPRESENTATION) + w_H_b = np.eye(4) + joints = np.ones(len(joints_name_list)) + M = kinDyn.mass_matrix_fun() + print(M(w_H_b, joints)) + + # If you want to use the symbolic version + w_H_b = cs.SX.eye(4) + joints = cs.SX.sym('joints', len(joints_name_list)) + M = kinDyn.mass_matrix_fun() + print(M(w_H_b, joints)) + + # This is usable also with casadi.MX + w_H_b = cs.MX.eye(4) + joints = cs.MX.sym('joints', len(joints_name_list)) + M = kinDyn.mass_matrix_fun() + print(M(w_H_b, joints)) + + w_H_f = kinDyn.forward_kinematics_fun() + print(w_H_f('frame_name', w_H_b, joints)) diff --git a/docs/quickstart/index.rst b/docs/quickstart/index.rst new file mode 100644 index 0000000..c0195c2 --- /dev/null +++ b/docs/quickstart/index.rst @@ -0,0 +1,14 @@ +Quickstart +=========== + +This section contains some snippets of code that show how to use the library. + +.. _quickstart: + +.. toctree:: + :maxdepth: 2 + + casadi + jax + pytorch + pytorch_batched diff --git a/docs/quickstart/jax.rst b/docs/quickstart/jax.rst new file mode 100644 index 0000000..01b84c7 --- /dev/null +++ b/docs/quickstart/jax.rst @@ -0,0 +1,60 @@ +Jax usage +========= + +The following example shows how to call an instance of the ``adam.jax.KinDynComputations`` class and use it to compute the mass matrix and forward dynamics of a floating-base robot. + +.. tip:: + We suggest to ``jax.jit`` the functions as it will make them run faster! + +.. note:: + When the functions are ``jax.jit``-ed, the first time you run them, it will take a bit longer to execute as they are being compiled by Jax. + +.. code-block:: python + + import adam + from adam.jax import KinDynComputations + import icub_models + import numpy as np + import jax.numpy as jnp + from jax import jit, vmap + + # if you want to icub-models https://github.com/robotology/icub-models to retrieve the urdf + model_path = icub_models.get_model_file("iCubGazeboV2_5") + # The joint list + joints_name_list = [ + 'torso_pitch', 'torso_roll', 'torso_yaw', 'l_shoulder_pitch', + 'l_shoulder_roll', 'l_shoulder_yaw', 'l_elbow', 'r_shoulder_pitch', + 'r_shoulder_roll', 'r_shoulder_yaw', 'r_elbow', 'l_hip_pitch', 'l_hip_roll', + 'l_hip_yaw', 'l_knee', 'l_ankle_pitch', 'l_ankle_roll', 'r_hip_pitch', + 'r_hip_roll', 'r_hip_yaw', 'r_knee', 'r_ankle_pitch', 'r_ankle_roll' + ] + + kinDyn = KinDynComputations(model_path, joints_name_list) + # choose the representation, if you want to use the body fixed representation + kinDyn.set_frame_velocity_representation(adam.Representations.BODY_FIXED_REPRESENTATION) + # or, if you want to use the mixed representation (that is the default) + kinDyn.set_frame_velocity_representation(adam.Representations.MIXED_REPRESENTATION) + w_H_b = np.eye(4) + joints = np.ones(len(joints_name_list)) + M = kinDyn.mass_matrix(w_H_b, joints) + print(M) + w_H_f = kinDyn.forward_kinematics('frame_name', w_H_b, joints) + + # IMPORTANT! The Jax Interface function execution can be slow! We suggest to jit them. + # For example: + + def frame_forward_kinematics(w_H_b, joints): + # This is needed since str is not a valid JAX type + return kinDyn.forward_kinematics('frame_name', w_H_b, joints) + + jitted_frame_fk = jit(frame_forward_kinematics) + w_H_f = jitted_frame_fk(w_H_b, joints) + + # In the same way, the functions can be also vmapped + vmapped_frame_fk = vmap(frame_forward_kinematics, in_axes=(0, 0)) + # which can be also jitted + jitted_vmapped_frame_fk = jit(vmapped_frame_fk) + # and called on a batch of data + joints_batch = jnp.tile(joints, (1024, 1)) + w_H_b_batch = jnp.tile(w_H_b, (1024, 1, 1)) + w_H_f_batch = jitted_vmapped_frame_fk(w_H_b_batch, joints_batch) diff --git a/docs/quickstart/pytorch.rst b/docs/quickstart/pytorch.rst new file mode 100644 index 0000000..077ea9f --- /dev/null +++ b/docs/quickstart/pytorch.rst @@ -0,0 +1,32 @@ +PyTorch usage +============= + +The following example shows how to call an instance of the ``adam.pytorch.KinDynComputations`` class and use it to compute the mass matrix and forward dynamics of a floating-base robot. + +.. code-block:: python + + import adam + from adam.pytorch import KinDynComputations + import icub_models + import numpy as np + + # if you want to icub-models https://github.com/robotology/icub-models to retrieve the urdf + model_path = icub_models.get_model_file("iCubGazeboV2_5") + # The joint list + joints_name_list = [ + 'torso_pitch', 'torso_roll', 'torso_yaw', 'l_shoulder_pitch', + 'l_shoulder_roll', 'l_shoulder_yaw', 'l_elbow', 'r_shoulder_pitch', + 'r_shoulder_roll', 'r_shoulder_yaw', 'r_elbow', 'l_hip_pitch', 'l_hip_roll', + 'l_hip_yaw', 'l_knee', 'l_ankle_pitch', 'l_ankle_roll', 'r_hip_pitch', + 'r_hip_roll', 'r_hip_yaw', 'r_knee', 'r_ankle_pitch', 'r_ankle_roll' + ] + + kinDyn = KinDynComputations(model_path, joints_name_list) + # choose the representation you want to use the body fixed representation + kinDyn.set_frame_velocity_representation(adam.Representations.BODY_FIXED_REPRESENTATION) + # or, if you want to use the mixed representation (that is the default) + kinDyn.set_frame_velocity_representation(adam.Representations.MIXED_REPRESENTATION) + w_H_b = np.eye(4) + joints = np.ones(len(joints_name_list)) + M = kinDyn.mass_matrix(w_H_b, joints) + print(M) diff --git a/docs/quickstart/pytorch_batched.rst b/docs/quickstart/pytorch_batched.rst new file mode 100644 index 0000000..9809e8e --- /dev/null +++ b/docs/quickstart/pytorch_batched.rst @@ -0,0 +1,40 @@ +PyTorch batched usage +===================== + +The following example shows how to call an instance of the ``adam.pytorch.KinDynComputationsBatch`` class and use it to compute the mass matrix and forward dynamics of a floating-base robot. + +.. note:: + The first time you run a function from this module, it will take a bit longer to execute as they are being compiled by JAX. + +.. code-block:: python + + + import adam + from adam.pytorch import KinDynComputationsBatch + import icub_models + + # if you want to icub-models + model_path = icub_models.get_model_file("iCubGazeboV2_5") + # The joint list + joints_name_list = [ + 'torso_pitch', 'torso_roll', 'torso_yaw', 'l_shoulder_pitch', + 'l_shoulder_roll', 'l_shoulder_yaw', 'l_elbow', 'r_shoulder_pitch', + 'r_shoulder_roll', 'r_shoulder_yaw', 'r_elbow', 'l_hip_pitch', 'l_hip_roll', + 'l_hip_yaw', 'l_knee', 'l_ankle_pitch', 'l_ankle_roll', 'r_hip_pitch', + 'r_hip_roll', 'r_hip_yaw', 'r_knee', 'r_ankle_pitch', 'r_ankle_roll' + ] + + kinDyn = KinDynComputationsBatch(model_path, joints_name_list) + # choose the representation you want to use the body fixed representation + kinDyn.set_frame_velocity_representation(adam.Representations.BODY_FIXED_REPRESENTATION) + # or, if you want to use the mixed representation (that is the default) + kinDyn.set_frame_velocity_representation(adam.Representations.MIXED_REPRESENTATION) + w_H_b = np.eye(4) + joints = np.ones(len(joints_name_list)) + + num_samples = 1024 + w_H_b_batch = torch.tensor(np.tile(w_H_b, (num_samples, 1, 1)), dtype=torch.float32) + joints_batch = torch.tensor(np.tile(joints, (num_samples, 1)), dtype=torch.float32) + + M = kinDyn.mass_matrix(w_H_b_batch, joints_batch) + w_H_f = kinDyn.forward_kinematics('frame_name', w_H_b_batch, joints_batch) diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..ce72c19 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,19 @@ +sphinx +sphinx-rtd-theme +sphinx-book-theme +sphinx-autodoc-typehints +sphinx-book-theme +sphinx-copybutton +sphinx-design +sphinx_fontawesome +sphinx-jinja2-compat +sphinx-multiversion +sphinx_rtd_theme +sphinx-toolbox +furo +myst-parser +graphviz +mock +sphinx-autoapi +adam-robotics[all] +idyntree diff --git a/src/adam/jax/computations.py b/src/adam/jax/computations.py index df5d9e4..c7a2bda 100644 --- a/src/adam/jax/computations.py +++ b/src/adam/jax/computations.py @@ -52,7 +52,7 @@ def mass_matrix(self, base_transform: jnp.array, joint_positions: jnp.array): joint_positions (jnp.array): The joints position Returns: - M (jax): Mass Matrix + M (jnp.array): Mass Matrix """ [M, _] = self.rbdalgos.crba(base_transform, joint_positions) return M.array @@ -125,12 +125,9 @@ def forward_kinematics( frame, base_transform, joint_positions ).array - def forward_kinematics_fun(self, frame): - return lambda T, joint_positions: self.forward_kinematics( - frame, T, joint_positions - ) - - def jacobian(self, frame: str, base_transform, joint_positions): + def jacobian( + self, frame: str, base_transform: jnp.array, joint_positions: jnp.array + ): """Returns the Jacobian relative to the specified frame Args: