mink 0.0.10__tar.gz → 0.0.12__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mink-0.0.10 → mink-0.0.12}/PKG-INFO +8 -7
- {mink-0.0.10 → mink-0.0.12}/README.md +6 -5
- {mink-0.0.10 → mink-0.0.12}/mink/__init__.py +19 -1
- {mink-0.0.10 → mink-0.0.12}/mink/configuration.py +23 -0
- {mink-0.0.10 → mink-0.0.12}/mink/exceptions.py +47 -0
- {mink-0.0.10 → mink-0.0.12}/mink/lie/se3.py +31 -0
- {mink-0.0.10 → mink-0.0.12}/mink/lie/so3.py +23 -1
- {mink-0.0.10 → mink-0.0.12}/mink/limits/__init__.py +0 -2
- {mink-0.0.10 → mink-0.0.12}/mink/limits/configuration_limit.py +3 -3
- {mink-0.0.10 → mink-0.0.12}/mink/limits/velocity_limit.py +1 -1
- {mink-0.0.10 → mink-0.0.12}/mink/solve_ik.py +35 -12
- {mink-0.0.10 → mink-0.0.12}/mink/tasks/__init__.py +4 -15
- mink-0.0.12/mink/tasks/com_task.py +159 -0
- mink-0.0.12/mink/tasks/damping_task.py +66 -0
- {mink-0.0.10 → mink-0.0.12}/mink/tasks/equality_constraint_task.py +58 -22
- {mink-0.0.10 → mink-0.0.12}/mink/tasks/frame_task.py +22 -3
- mink-0.0.12/mink/tasks/kinetic_energy_regularization_task.py +73 -0
- {mink-0.0.10 → mink-0.0.12}/mink/tasks/posture_task.py +28 -14
- {mink-0.0.10 → mink-0.0.12}/mink/tasks/relative_frame_task.py +1 -1
- {mink-0.0.10 → mink-0.0.12}/mink/tasks/task.py +23 -5
- {mink-0.0.10 → mink-0.0.12}/pyproject.toml +11 -9
- mink-0.0.10/mink/limits/exceptions.py +0 -7
- mink-0.0.10/mink/tasks/com_task.py +0 -97
- mink-0.0.10/mink/tasks/damping_task.py +0 -20
- mink-0.0.10/mink/tasks/exceptions.py +0 -31
- {mink-0.0.10 → mink-0.0.12}/LICENSE +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/.gitignore +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/@plugins_snapshot.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/__future__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/__future__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/_ast.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/_ast.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/_codecs.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/_codecs.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/_collections_abc.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/_collections_abc.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/_ctypes.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/_ctypes.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/_thread.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/_thread.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/_typeshed/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/_typeshed/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/_warnings.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/_warnings.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/abc.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/abc.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/array.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/array.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/ast.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/ast.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/builtins.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/builtins.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/codecs.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/codecs.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/collections/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/collections/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/collections/abc.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/collections/abc.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/contextlib.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/contextlib.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/ctypes/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/ctypes/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/dataclasses.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/dataclasses.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/datetime.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/datetime.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/email/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/email/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/email/charset.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/email/charset.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/email/contentmanager.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/email/contentmanager.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/email/errors.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/email/errors.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/email/header.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/email/header.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/email/message.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/email/message.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/email/policy.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/email/policy.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/enum.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/enum.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/genericpath.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/genericpath.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/importlib/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/importlib/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/importlib/abc.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/importlib/abc.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/importlib/machinery.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/importlib/machinery.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/importlib/metadata/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/importlib/metadata/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/importlib/metadata/_meta.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/importlib/metadata/_meta.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/importlib/readers.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/importlib/readers.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/importlib/resources/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/importlib/resources/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/importlib/resources/abc.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/importlib/resources/abc.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/io.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/io.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/logging/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/logging/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/math.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/math.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/mink/limits/limit.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/mink/limits/limit.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/mmap.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/mmap.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_pytesttester.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_pytesttester.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_add_docstring.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_add_docstring.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_array_like.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_array_like.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_callable.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_callable.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_char_codes.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_char_codes.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_dtype_like.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_dtype_like.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_extended_precision.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_extended_precision.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_nbit.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_nbit.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_nested_sequence.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_nested_sequence.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_scalars.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_scalars.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_shape.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_shape.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_ufunc.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_typing/_ufunc.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_utils/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_utils/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_utils/_convertions.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/_utils/_convertions.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/_asarray.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/_asarray.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/_internal.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/_internal.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/_type_aliases.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/_type_aliases.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/_ufunc_config.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/_ufunc_config.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/arrayprint.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/arrayprint.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/defchararray.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/defchararray.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/einsumfunc.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/einsumfunc.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/fromnumeric.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/fromnumeric.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/function_base.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/function_base.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/multiarray.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/multiarray.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/numeric.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/numeric.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/numerictypes.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/numerictypes.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/records.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/records.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/shape_base.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/shape_base.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/umath.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/core/umath.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/ctypeslib.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/ctypeslib.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/dtypes.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/dtypes.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/exceptions.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/exceptions.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/fft/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/fft/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/fft/_pocketfft.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/fft/_pocketfft.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/fft/helper.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/fft/helper.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/_version.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/_version.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/arraypad.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/arraypad.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/arraysetops.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/arraysetops.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/arrayterator.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/arrayterator.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/format.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/format.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/function_base.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/function_base.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/histograms.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/histograms.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/index_tricks.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/index_tricks.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/mixins.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/mixins.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/nanfunctions.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/nanfunctions.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/npyio.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/npyio.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/polynomial.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/polynomial.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/scimath.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/scimath.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/shape_base.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/shape_base.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/stride_tricks.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/stride_tricks.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/twodim_base.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/twodim_base.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/type_check.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/type_check.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/ufunclike.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/ufunclike.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/utils.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/lib/utils.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/linalg/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/linalg/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/linalg/linalg.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/linalg/linalg.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/ma/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/ma/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/ma/core.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/ma/core.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/ma/extras.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/ma/extras.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/ma/mrecords.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/ma/mrecords.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/matrixlib/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/matrixlib/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/matrixlib/defmatrix.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/matrixlib/defmatrix.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/polynomial/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/polynomial/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/polynomial/_polybase.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/polynomial/_polybase.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/polynomial/chebyshev.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/polynomial/chebyshev.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/polynomial/hermite.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/polynomial/hermite.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/polynomial/hermite_e.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/polynomial/hermite_e.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/polynomial/laguerre.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/polynomial/laguerre.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/polynomial/legendre.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/polynomial/legendre.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/polynomial/polynomial.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/polynomial/polynomial.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/polynomial/polyutils.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/polynomial/polyutils.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/random/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/random/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/random/_generator.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/random/_generator.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/random/_mt19937.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/random/_mt19937.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/random/_pcg64.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/random/_pcg64.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/random/_philox.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/random/_philox.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/random/_sfc64.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/random/_sfc64.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/random/bit_generator.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/random/bit_generator.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/random/mtrand.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/random/mtrand.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/testing/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/testing/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/testing/_private/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/testing/_private/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/testing/_private/utils.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/testing/_private/utils.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/typing/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/typing/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/version.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/numpy/version.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/os/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/os/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/os/path.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/os/path.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/pathlib.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/pathlib.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/posixpath.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/posixpath.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/re.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/re.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/sre_compile.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/sre_compile.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/sre_constants.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/sre_constants.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/sre_parse.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/sre_parse.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/string.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/string.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/subprocess.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/subprocess.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/sys/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/sys/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/sys/_monitoring.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/sys/_monitoring.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/textwrap.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/textwrap.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/threading.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/threading.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/time.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/time.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/types.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/types.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/typing.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/typing.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/typing_extensions.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/typing_extensions.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/unittest/__init__.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/unittest/__init__.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/unittest/_log.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/unittest/_log.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/unittest/async_case.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/unittest/async_case.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/unittest/case.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/unittest/case.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/unittest/loader.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/unittest/loader.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/unittest/main.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/unittest/main.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/unittest/result.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/unittest/result.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/unittest/runner.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/unittest/runner.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/unittest/signals.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/unittest/signals.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/unittest/suite.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/unittest/suite.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/warnings.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/warnings.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/zipfile.data.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/3.12/zipfile.meta.json +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/.mypy_cache/CACHEDIR.TAG +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/constants.py +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/contrib/__init__.py +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/contrib/keyboard_teleop/KEYBOARD.md +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/contrib/keyboard_teleop/__init__.py +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/contrib/keyboard_teleop/keycodes.py +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/contrib/keyboard_teleop/teleop_mocap.py +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/lie/__init__.py +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/lie/base.py +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/lie/utils.py +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/limits/collision_avoidance_limit.py +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/limits/limit.py +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/py.typed +0 -0
- {mink-0.0.10 → mink-0.0.12}/mink/utils.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: mink
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.12
|
4
4
|
Summary: mink: MuJoCo inverse kinematics.
|
5
5
|
Keywords: inverse,kinematics,mujoco
|
6
6
|
Author-email: Kevin Zakka <zakka@berkeley.edu>
|
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.10
|
17
17
|
Classifier: Programming Language :: Python :: 3.11
|
18
18
|
Classifier: Programming Language :: Python :: 3.12
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
19
20
|
Classifier: Topic :: Scientific/Engineering
|
20
21
|
License-File: LICENSE
|
21
22
|
Requires-Dist: mujoco >= 3.1.6
|
@@ -27,7 +28,6 @@ Requires-Dist: black ; extra == "dev"
|
|
27
28
|
Requires-Dist: mink[test] ; extra == "dev"
|
28
29
|
Requires-Dist: mypy ; extra == "dev"
|
29
30
|
Requires-Dist: ruff ; extra == "dev"
|
30
|
-
Requires-Dist: dm_control >= 1.0.20 ; extra == "examples"
|
31
31
|
Requires-Dist: loop-rate-limiters >= 0.1.0 ; extra == "examples"
|
32
32
|
Requires-Dist: qpsolvers[daqp] >= 4.3.1 ; extra == "examples"
|
33
33
|
Requires-Dist: osqp >=0.6.2,<1 ; extra == "examples"
|
@@ -59,6 +59,7 @@ Features include:
|
|
59
59
|
* Task specification in configuration or operational space;
|
60
60
|
* Limits on joint positions and velocities;
|
61
61
|
* Collision avoidance between any geom pair;
|
62
|
+
* Support for closed-chain kinematics (loop closures) via [equality constraints](https://mujoco.readthedocs.io/en/stable/computation/index.html#coequality);
|
62
63
|
* Lie group interface for rigid body transformations.
|
63
64
|
|
64
65
|
For usage and API reference, see the [documentation](https://kevinzakka.github.io/mink/).
|
@@ -66,14 +67,14 @@ For usage and API reference, see the [documentation](https://kevinzakka.github.i
|
|
66
67
|
If you use mink in your research, please cite it as follows:
|
67
68
|
|
68
69
|
```bibtex
|
69
|
-
@software{
|
70
|
+
@software{Zakka_Mink_Python_inverse_2025,
|
70
71
|
author = {Zakka, Kevin},
|
71
|
-
license = {Apache-2.0},
|
72
|
-
month = jul,
|
73
72
|
title = {{Mink: Python inverse kinematics based on MuJoCo}},
|
73
|
+
year = {2025},
|
74
|
+
month = may,
|
75
|
+
version = {0.0.11},
|
74
76
|
url = {https://github.com/kevinzakka/mink},
|
75
|
-
|
76
|
-
year = {2024}
|
77
|
+
license = {Apache-2.0}
|
77
78
|
}
|
78
79
|
```
|
79
80
|
|
@@ -12,6 +12,7 @@ Features include:
|
|
12
12
|
* Task specification in configuration or operational space;
|
13
13
|
* Limits on joint positions and velocities;
|
14
14
|
* Collision avoidance between any geom pair;
|
15
|
+
* Support for closed-chain kinematics (loop closures) via [equality constraints](https://mujoco.readthedocs.io/en/stable/computation/index.html#coequality);
|
15
16
|
* Lie group interface for rigid body transformations.
|
16
17
|
|
17
18
|
For usage and API reference, see the [documentation](https://kevinzakka.github.io/mink/).
|
@@ -19,14 +20,14 @@ For usage and API reference, see the [documentation](https://kevinzakka.github.i
|
|
19
20
|
If you use mink in your research, please cite it as follows:
|
20
21
|
|
21
22
|
```bibtex
|
22
|
-
@software{
|
23
|
+
@software{Zakka_Mink_Python_inverse_2025,
|
23
24
|
author = {Zakka, Kevin},
|
24
|
-
license = {Apache-2.0},
|
25
|
-
month = jul,
|
26
25
|
title = {{Mink: Python inverse kinematics based on MuJoCo}},
|
26
|
+
year = {2025},
|
27
|
+
month = may,
|
28
|
+
version = {0.0.11},
|
27
29
|
url = {https://github.com/kevinzakka/mink},
|
28
|
-
|
29
|
-
year = {2024}
|
30
|
+
license = {Apache-2.0}
|
30
31
|
}
|
31
32
|
```
|
32
33
|
|
@@ -9,11 +9,20 @@ from .constants import (
|
|
9
9
|
SUPPORTED_FRAMES,
|
10
10
|
)
|
11
11
|
from .exceptions import (
|
12
|
+
IntegrationTimestepNotSet,
|
13
|
+
InvalidConstraint,
|
14
|
+
InvalidDamping,
|
12
15
|
InvalidFrame,
|
16
|
+
InvalidGain,
|
13
17
|
InvalidKeyframe,
|
14
18
|
InvalidMocapBody,
|
19
|
+
InvalidTarget,
|
20
|
+
LimitDefinitionError,
|
15
21
|
MinkError,
|
22
|
+
NoSolutionFound,
|
16
23
|
NotWithinConfigurationLimits,
|
24
|
+
TargetNotSet,
|
25
|
+
TaskDefinitionError,
|
17
26
|
UnsupportedFrame,
|
18
27
|
)
|
19
28
|
from .lie import SE3, SO3, MatrixLieGroup
|
@@ -30,10 +39,10 @@ from .tasks import (
|
|
30
39
|
DampingTask,
|
31
40
|
EqualityConstraintTask,
|
32
41
|
FrameTask,
|
42
|
+
KineticEnergyRegularizationTask,
|
33
43
|
Objective,
|
34
44
|
PostureTask,
|
35
45
|
RelativeFrameTask,
|
36
|
-
TargetNotSet,
|
37
46
|
Task,
|
38
47
|
)
|
39
48
|
from .utils import (
|
@@ -55,6 +64,7 @@ __all__ = (
|
|
55
64
|
"RelativeFrameTask",
|
56
65
|
"PostureTask",
|
57
66
|
"Task",
|
67
|
+
"KineticEnergyRegularizationTask",
|
58
68
|
"EqualityConstraintTask",
|
59
69
|
"Objective",
|
60
70
|
"ConfigurationLimit",
|
@@ -72,6 +82,14 @@ __all__ = (
|
|
72
82
|
"NotWithinConfigurationLimits",
|
73
83
|
"TargetNotSet",
|
74
84
|
"InvalidMocapBody",
|
85
|
+
"InvalidConstraint",
|
86
|
+
"InvalidDamping",
|
87
|
+
"InvalidGain",
|
88
|
+
"InvalidTarget",
|
89
|
+
"LimitDefinitionError",
|
90
|
+
"TaskDefinitionError",
|
91
|
+
"IntegrationTimestepNotSet",
|
92
|
+
"NoSolutionFound",
|
75
93
|
"SUPPORTED_FRAMES",
|
76
94
|
"FRAME_TO_ENUM",
|
77
95
|
"FRAME_TO_JAC_FUNC",
|
@@ -30,6 +30,7 @@ class Configuration:
|
|
30
30
|
* Running forward kinematics to update the state.
|
31
31
|
* Checking configuration limits.
|
32
32
|
* Computing Jacobians for different frames.
|
33
|
+
* Computing the joint-space inertia matrix.
|
33
34
|
* Retrieving frame transforms relative to the world frame.
|
34
35
|
* Integrating velocities to update configurations.
|
35
36
|
"""
|
@@ -84,6 +85,10 @@ class Configuration:
|
|
84
85
|
safety_break: If True, stop execution and raise an exception if the current
|
85
86
|
configuration is outside limits. If False, print a warning and continue
|
86
87
|
execution.
|
88
|
+
|
89
|
+
Raises:
|
90
|
+
NotWithinConfigurationLimits: If the current configuration is outside
|
91
|
+
the joint limits.
|
87
92
|
"""
|
88
93
|
for jnt in range(self.model.njnt):
|
89
94
|
jnt_type = self.model.jnt_type[jnt]
|
@@ -237,6 +242,24 @@ class Configuration:
|
|
237
242
|
mujoco.mj_integratePos(self.model, self.data.qpos, velocity, dt)
|
238
243
|
self.update()
|
239
244
|
|
245
|
+
def get_inertia_matrix(self) -> np.ndarray:
|
246
|
+
r"""Return the joint-space inertia matrix at the current configuration.
|
247
|
+
|
248
|
+
Returns:
|
249
|
+
The joint-space inertia matrix :math:`M(\mathbf{q})`.
|
250
|
+
"""
|
251
|
+
# Run the composite rigid body inertia (CRB) algorithm to populate the joint
|
252
|
+
# space inertia matrix data.qM.
|
253
|
+
if mujoco.mj_version() >= 334:
|
254
|
+
mujoco.mj_makeM(self.model, self.data)
|
255
|
+
else:
|
256
|
+
mujoco.mj_crb(self.model, self.data)
|
257
|
+
# data.qM is stored in a custom sparse format and can be converted to dense
|
258
|
+
# format using mujoco.mj_fullM.
|
259
|
+
M = np.empty((self.nv, self.nv), dtype=np.float64)
|
260
|
+
mujoco.mj_fullM(self.model, M, self.data.qM)
|
261
|
+
return M
|
262
|
+
|
240
263
|
# Aliases.
|
241
264
|
|
242
265
|
@property
|
@@ -9,6 +9,13 @@ class MinkError(Exception):
|
|
9
9
|
"""Base class for Mink exceptions."""
|
10
10
|
|
11
11
|
|
12
|
+
class NoSolutionFound(MinkError):
|
13
|
+
"""Exception raised when the QP solver fails to find a solution."""
|
14
|
+
|
15
|
+
def __init__(self, solver_name: str):
|
16
|
+
super().__init__(f"QP solver {solver_name} failed to find a solution.")
|
17
|
+
|
18
|
+
|
12
19
|
class UnsupportedFrame(MinkError):
|
13
20
|
"""Exception raised when a frame type is unsupported."""
|
14
21
|
|
@@ -96,3 +103,43 @@ class NotWithinConfigurationLimits(MinkError):
|
|
96
103
|
f"{lower} <= {value} <= {upper}"
|
97
104
|
)
|
98
105
|
super().__init__(message)
|
106
|
+
|
107
|
+
|
108
|
+
class TaskDefinitionError(MinkError):
|
109
|
+
"""Exception raised when a task definition is ill-formed."""
|
110
|
+
|
111
|
+
|
112
|
+
class IntegrationTimestepNotSet(MinkError):
|
113
|
+
"""Exception raised when the integration timestep is not set."""
|
114
|
+
|
115
|
+
def __init__(self, cls_name: str):
|
116
|
+
message = f"No integration timestep set for {cls_name}"
|
117
|
+
super().__init__(message)
|
118
|
+
|
119
|
+
|
120
|
+
class TargetNotSet(MinkError):
|
121
|
+
"""Exception raised when attempting to use a task with an unset target."""
|
122
|
+
|
123
|
+
def __init__(self, cls_name: str):
|
124
|
+
message = f"No target set for {cls_name}"
|
125
|
+
super().__init__(message)
|
126
|
+
|
127
|
+
|
128
|
+
class InvalidTarget(MinkError):
|
129
|
+
"""Exception raised when the target is invalid."""
|
130
|
+
|
131
|
+
|
132
|
+
class InvalidGain(MinkError):
|
133
|
+
"""Exception raised when the gain is outside the valid range."""
|
134
|
+
|
135
|
+
|
136
|
+
class InvalidDamping(MinkError):
|
137
|
+
"""Exception raised when the damping is outside the valid range."""
|
138
|
+
|
139
|
+
|
140
|
+
class InvalidConstraint(MinkError):
|
141
|
+
"""Exception raised when a constraint is invalid."""
|
142
|
+
|
143
|
+
|
144
|
+
class LimitDefinitionError(MinkError):
|
145
|
+
"""Exception raised when a limit definition is ill-formed."""
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
from dataclasses import dataclass
|
4
|
+
from typing import Tuple
|
4
5
|
|
5
6
|
import mujoco
|
6
7
|
import numpy as np
|
@@ -221,6 +222,36 @@ class SE3(MatrixLieGroup):
|
|
221
222
|
ljacinv_se3[3:, 3:] = ljacinv_so3
|
222
223
|
return ljacinv_se3
|
223
224
|
|
225
|
+
def clamp(
|
226
|
+
self,
|
227
|
+
x_translation: Tuple[float, float] = (-np.inf, np.inf),
|
228
|
+
y_translation: Tuple[float, float] = (-np.inf, np.inf),
|
229
|
+
z_translation: Tuple[float, float] = (-np.inf, np.inf),
|
230
|
+
roll_radians: Tuple[float, float] = (-np.inf, np.inf),
|
231
|
+
pitch_radians: Tuple[float, float] = (-np.inf, np.inf),
|
232
|
+
yaw_radians: Tuple[float, float] = (-np.inf, np.inf),
|
233
|
+
) -> SE3:
|
234
|
+
"""Clamp a SE3 within translation and RPY limits.
|
235
|
+
|
236
|
+
Args:
|
237
|
+
x_translation: The (lower, upper) limits for translation along the x axis.
|
238
|
+
y_translation: The (lower, upper) limits for translation along the y axis.
|
239
|
+
z_translation: The (lower, upper) limits for translation along the z axis.
|
240
|
+
roll_radians: The (lower, upper) limits for the roll.
|
241
|
+
pitch_radians: The (lower, upper) limits for the pitch.
|
242
|
+
yaw_radians: The (lower, upper) limits for the yaw.
|
243
|
+
|
244
|
+
Returns:
|
245
|
+
A SE3 within the translation and RPY limits.
|
246
|
+
"""
|
247
|
+
translation_limits = np.array([x_translation, y_translation, z_translation])
|
248
|
+
return SE3.from_rotation_and_translation(
|
249
|
+
rotation=self.rotation().clamp(roll_radians, pitch_radians, yaw_radians),
|
250
|
+
translation=np.clip(
|
251
|
+
self.translation(), translation_limits[:, 0], translation_limits[:, 1]
|
252
|
+
),
|
253
|
+
)
|
254
|
+
|
224
255
|
|
225
256
|
# Eqn 180.
|
226
257
|
def _getQ(c) -> np.ndarray:
|
@@ -1,7 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
from dataclasses import dataclass
|
4
|
-
from typing import NamedTuple
|
4
|
+
from typing import NamedTuple, Tuple
|
5
5
|
|
6
6
|
import mujoco
|
7
7
|
import numpy as np
|
@@ -260,3 +260,25 @@ class SO3(MatrixLieGroup):
|
|
260
260
|
ljacinv[1, 1] += 1.0
|
261
261
|
ljacinv[2, 2] += 1.0
|
262
262
|
return ljacinv
|
263
|
+
|
264
|
+
def clamp(
|
265
|
+
self,
|
266
|
+
roll_radians: Tuple[float, float] = (-np.inf, np.inf),
|
267
|
+
pitch_radians: Tuple[float, float] = (-np.inf, np.inf),
|
268
|
+
yaw_radians: Tuple[float, float] = (-np.inf, np.inf),
|
269
|
+
) -> SO3:
|
270
|
+
"""Clamp a SO3 within RPY limits.
|
271
|
+
|
272
|
+
Args:
|
273
|
+
roll_radians: The (lower, upper) limits for the roll.
|
274
|
+
pitch_radians: The (lower, upper) limits for the pitch.
|
275
|
+
yaw_radians: The (lower, upper) limits for the yaw.
|
276
|
+
|
277
|
+
Returns:
|
278
|
+
A SO3 within the RPY limits.
|
279
|
+
"""
|
280
|
+
return SO3.from_rpy_radians(
|
281
|
+
roll=np.clip(self.compute_roll_radians(), *roll_radians),
|
282
|
+
pitch=np.clip(self.compute_pitch_radians(), *pitch_radians),
|
283
|
+
yaw=np.clip(self.compute_yaw_radians(), *yaw_radians),
|
284
|
+
)
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
from .collision_avoidance_limit import CollisionAvoidanceLimit
|
4
4
|
from .configuration_limit import ConfigurationLimit
|
5
|
-
from .exceptions import LimitDefinitionError
|
6
5
|
from .limit import Constraint, Limit
|
7
6
|
from .velocity_limit import VelocityLimit
|
8
7
|
|
@@ -12,5 +11,4 @@ __all__ = (
|
|
12
11
|
"Constraint",
|
13
12
|
"Limit",
|
14
13
|
"VelocityLimit",
|
15
|
-
"LimitDefinitionError",
|
16
14
|
)
|
@@ -7,7 +7,7 @@ import numpy as np
|
|
7
7
|
|
8
8
|
from ..configuration import Configuration
|
9
9
|
from ..constants import dof_width, qpos_width
|
10
|
-
from
|
10
|
+
from ..exceptions import LimitDefinitionError
|
11
11
|
from .limit import Constraint, Limit
|
12
12
|
|
13
13
|
|
@@ -98,7 +98,7 @@ class ConfigurationLimit(Limit):
|
|
98
98
|
return Constraint()
|
99
99
|
|
100
100
|
# Upper.
|
101
|
-
delta_q_max = np.
|
101
|
+
delta_q_max = np.empty((self.model.nv,))
|
102
102
|
mujoco.mj_differentiatePos(
|
103
103
|
m=self.model,
|
104
104
|
qvel=delta_q_max,
|
@@ -108,7 +108,7 @@ class ConfigurationLimit(Limit):
|
|
108
108
|
)
|
109
109
|
|
110
110
|
# Lower.
|
111
|
-
delta_q_min = np.
|
111
|
+
delta_q_min = np.empty((self.model.nv,))
|
112
112
|
mujoco.mj_differentiatePos(
|
113
113
|
m=self.model,
|
114
114
|
qvel=delta_q_min,
|
@@ -6,12 +6,13 @@ import numpy as np
|
|
6
6
|
import qpsolvers
|
7
7
|
|
8
8
|
from .configuration import Configuration
|
9
|
+
from .exceptions import NoSolutionFound
|
9
10
|
from .limits import ConfigurationLimit, Limit
|
10
|
-
from .tasks import
|
11
|
+
from .tasks import BaseTask, Objective
|
11
12
|
|
12
13
|
|
13
14
|
def _compute_qp_objective(
|
14
|
-
configuration: Configuration, tasks: Sequence[
|
15
|
+
configuration: Configuration, tasks: Sequence[BaseTask], damping: float
|
15
16
|
) -> Objective:
|
16
17
|
H = np.eye(configuration.model.nv) * damping
|
17
18
|
c = np.zeros(configuration.model.nv)
|
@@ -42,18 +43,31 @@ def _compute_qp_inequalities(
|
|
42
43
|
|
43
44
|
def build_ik(
|
44
45
|
configuration: Configuration,
|
45
|
-
tasks: Sequence[
|
46
|
+
tasks: Sequence[BaseTask],
|
46
47
|
dt: float,
|
47
48
|
damping: float = 1e-12,
|
48
49
|
limits: Optional[Sequence[Limit]] = None,
|
49
50
|
) -> qpsolvers.Problem:
|
50
|
-
"""Build quadratic program
|
51
|
+
r"""Build the quadratic program given the current configuration and tasks.
|
52
|
+
|
53
|
+
The quadratic program is defined as:
|
54
|
+
|
55
|
+
.. math::
|
56
|
+
|
57
|
+
\begin{align*}
|
58
|
+
\min_{\Delta q} & \frac{1}{2} \Delta q^T H \Delta q + c^T \Delta q \\
|
59
|
+
\text{s.t.} \quad & G \Delta q \leq h
|
60
|
+
\end{align*}
|
61
|
+
|
62
|
+
where :math:`\Delta q = v / dt` is the vector of joint displacements.
|
51
63
|
|
52
64
|
Args:
|
53
65
|
configuration: Robot configuration.
|
54
66
|
tasks: List of kinematic tasks.
|
55
67
|
dt: Integration timestep in [s].
|
56
|
-
damping: Levenberg-Marquardt damping.
|
68
|
+
damping: Levenberg-Marquardt damping. Higher values improve numerical
|
69
|
+
stability but slow down task convergence. This value applies to all
|
70
|
+
dofs, including floating-base coordinates.
|
57
71
|
limits: List of limits to enforce. Set to empty list to disable. If None,
|
58
72
|
defaults to a configuration limit.
|
59
73
|
|
@@ -67,7 +81,7 @@ def build_ik(
|
|
67
81
|
|
68
82
|
def solve_ik(
|
69
83
|
configuration: Configuration,
|
70
|
-
tasks: Sequence[
|
84
|
+
tasks: Sequence[BaseTask],
|
71
85
|
dt: float,
|
72
86
|
solver: str,
|
73
87
|
damping: float = 1e-12,
|
@@ -75,7 +89,7 @@ def solve_ik(
|
|
75
89
|
limits: Optional[Sequence[Limit]] = None,
|
76
90
|
**kwargs,
|
77
91
|
) -> np.ndarray:
|
78
|
-
"""Solve the differential inverse kinematics problem.
|
92
|
+
r"""Solve the differential inverse kinematics problem.
|
79
93
|
|
80
94
|
Computes a velocity tangent to the current robot configuration. The computed
|
81
95
|
velocity satisfies at (weighted) best the set of provided kinematic tasks.
|
@@ -85,7 +99,9 @@ def solve_ik(
|
|
85
99
|
tasks: List of kinematic tasks.
|
86
100
|
dt: Integration timestep in [s].
|
87
101
|
solver: Backend quadratic programming (QP) solver.
|
88
|
-
damping: Levenberg-Marquardt damping.
|
102
|
+
damping: Levenberg-Marquardt damping applied to all tasks. Higher values
|
103
|
+
improve numerical stability but slow down task convergence. This
|
104
|
+
value applies to all dofs, including floating-base coordinates.
|
89
105
|
safety_break: If True, stop execution and raise an exception if
|
90
106
|
the current configuration is outside limits. If False, print a
|
91
107
|
warning and continue execution.
|
@@ -93,13 +109,20 @@ def solve_ik(
|
|
93
109
|
defaults to a configuration limit.
|
94
110
|
kwargs: Keyword arguments to forward to the backend QP solver.
|
95
111
|
|
112
|
+
Raises:
|
113
|
+
NotWithinConfigurationLimits: If the current configuration is outside
|
114
|
+
the joint limits and `safety_break` is True.
|
115
|
+
NoSolutionFound: If the QP solver fails to find a solution.
|
116
|
+
|
96
117
|
Returns:
|
97
|
-
Velocity
|
118
|
+
Velocity :math:`v` in tangent space.
|
98
119
|
"""
|
99
120
|
configuration.check_limits(safety_break=safety_break)
|
100
121
|
problem = build_ik(configuration, tasks, dt, damping, limits)
|
101
122
|
result = qpsolvers.solve_problem(problem, solver=solver, **kwargs)
|
102
|
-
|
103
|
-
|
104
|
-
|
123
|
+
if not result.found:
|
124
|
+
raise NoSolutionFound(solver)
|
125
|
+
delta_q = result.x
|
126
|
+
assert delta_q is not None
|
127
|
+
v: np.ndarray = delta_q / dt
|
105
128
|
return v
|
@@ -3,20 +3,14 @@
|
|
3
3
|
from .com_task import ComTask
|
4
4
|
from .damping_task import DampingTask
|
5
5
|
from .equality_constraint_task import EqualityConstraintTask
|
6
|
-
from .exceptions import (
|
7
|
-
InvalidConstraint,
|
8
|
-
InvalidDamping,
|
9
|
-
InvalidGain,
|
10
|
-
InvalidTarget,
|
11
|
-
TargetNotSet,
|
12
|
-
TaskDefinitionError,
|
13
|
-
)
|
14
6
|
from .frame_task import FrameTask
|
7
|
+
from .kinetic_energy_regularization_task import KineticEnergyRegularizationTask
|
15
8
|
from .posture_task import PostureTask
|
16
9
|
from .relative_frame_task import RelativeFrameTask
|
17
|
-
from .task import Objective, Task
|
10
|
+
from .task import BaseTask, Objective, Task
|
18
11
|
|
19
12
|
__all__ = (
|
13
|
+
"BaseTask",
|
20
14
|
"ComTask",
|
21
15
|
"FrameTask",
|
22
16
|
"Objective",
|
@@ -24,11 +18,6 @@ __all__ = (
|
|
24
18
|
"PostureTask",
|
25
19
|
"RelativeFrameTask",
|
26
20
|
"Task",
|
27
|
-
"TargetNotSet",
|
28
|
-
"InvalidTarget",
|
29
|
-
"TaskDefinitionError",
|
30
|
-
"InvalidConstraint",
|
31
|
-
"InvalidGain",
|
32
|
-
"InvalidDamping",
|
33
21
|
"EqualityConstraintTask",
|
22
|
+
"KineticEnergyRegularizationTask",
|
34
23
|
)
|
@@ -0,0 +1,159 @@
|
|
1
|
+
"""Center-of-mass task implementation."""
|
2
|
+
|
3
|
+
from __future__ import annotations
|
4
|
+
|
5
|
+
from typing import Optional
|
6
|
+
|
7
|
+
import mujoco
|
8
|
+
import numpy as np
|
9
|
+
import numpy.typing as npt
|
10
|
+
|
11
|
+
from ..configuration import Configuration
|
12
|
+
from ..exceptions import InvalidTarget, TargetNotSet, TaskDefinitionError
|
13
|
+
from .task import Task
|
14
|
+
|
15
|
+
|
16
|
+
class ComTask(Task):
|
17
|
+
"""Regulate the center-of-mass (CoM) of a robot.
|
18
|
+
|
19
|
+
Attributes:
|
20
|
+
target_com: Target position of the CoM.
|
21
|
+
|
22
|
+
Example:
|
23
|
+
|
24
|
+
.. code-block:: python
|
25
|
+
|
26
|
+
com_task = ComTask(model, cost=1.0)
|
27
|
+
|
28
|
+
# Update the target CoM directly.
|
29
|
+
com_desired = np.zeros(3)
|
30
|
+
com_task.set_target(com_desired)
|
31
|
+
|
32
|
+
# Or from a keyframe defined in the model.
|
33
|
+
configuration.update_from_keyframe("home")
|
34
|
+
com_task.set_target_from_configuration(configuration)
|
35
|
+
"""
|
36
|
+
|
37
|
+
k: int = 3
|
38
|
+
target_com: Optional[np.ndarray]
|
39
|
+
|
40
|
+
def __init__(
|
41
|
+
self,
|
42
|
+
cost: npt.ArrayLike,
|
43
|
+
gain: float = 1.0,
|
44
|
+
lm_damping: float = 0.0,
|
45
|
+
):
|
46
|
+
super().__init__(cost=np.zeros((self.k,)), gain=gain, lm_damping=lm_damping)
|
47
|
+
self.target_com = None
|
48
|
+
|
49
|
+
self.set_cost(cost)
|
50
|
+
|
51
|
+
def set_cost(self, cost: npt.ArrayLike) -> None:
|
52
|
+
"""Set the cost of the CoM task.
|
53
|
+
|
54
|
+
Args:
|
55
|
+
cost: A vector of shape (1,) (aka identical cost for all coordinates),
|
56
|
+
or (3,) (aka different costs for each coordinate).
|
57
|
+
"""
|
58
|
+
cost = np.atleast_1d(cost)
|
59
|
+
if cost.ndim != 1 or cost.shape[0] not in (1, self.k):
|
60
|
+
raise TaskDefinitionError(
|
61
|
+
f"{self.__class__.__name__} cost must be a vector of shape (1,) "
|
62
|
+
f"(aka identical cost for all coordinates) or ({self.k},). "
|
63
|
+
f"Got {cost.shape}"
|
64
|
+
)
|
65
|
+
if not np.all(cost >= 0.0):
|
66
|
+
raise TaskDefinitionError(f"{self.__class__.__name__} cost must be >= 0")
|
67
|
+
self.cost[:] = cost
|
68
|
+
|
69
|
+
def set_target(self, target_com: npt.ArrayLike) -> None:
|
70
|
+
"""Set the target CoM position in the world frame.
|
71
|
+
|
72
|
+
Args:
|
73
|
+
target_com: A vector of shape (3,) representing the desired
|
74
|
+
center-of-mass position in the world frame.
|
75
|
+
"""
|
76
|
+
target_com = np.atleast_1d(target_com)
|
77
|
+
if target_com.ndim != 1 or target_com.shape[0] != (self.k):
|
78
|
+
raise InvalidTarget(
|
79
|
+
f"Expected target CoM to have shape ({self.k},) but got "
|
80
|
+
f"{target_com.shape}"
|
81
|
+
)
|
82
|
+
self.target_com = target_com.copy()
|
83
|
+
|
84
|
+
def set_target_from_configuration(self, configuration: Configuration) -> None:
|
85
|
+
"""Set the target CoM from a given robot configuration.
|
86
|
+
|
87
|
+
Args:
|
88
|
+
configuration: Robot configuration :math:`q`.
|
89
|
+
"""
|
90
|
+
self.set_target(configuration.data.subtree_com[1])
|
91
|
+
|
92
|
+
def compute_error(self, configuration: Configuration) -> np.ndarray:
|
93
|
+
r"""Compute the CoM task error.
|
94
|
+
|
95
|
+
The center of mass :math:`c(q)` for a collection of bodies :math:`\mathcal{B}`
|
96
|
+
is the mass-weighted average of their individual centers of mass. After running
|
97
|
+
forward kinematics, in particular after calling ``mj_comPos``, MuJoCo stores
|
98
|
+
the CoM of each subtree in ``data.subtree_com``. This task uses the CoM of the
|
99
|
+
subtree starting from body 1, which is the entire robot excluding the world
|
100
|
+
body (body 0).
|
101
|
+
|
102
|
+
The task error :math:`e(q)` is the difference between the current CoM
|
103
|
+
:math:`c(q)` and the target CoM :math:`c^*`:
|
104
|
+
|
105
|
+
.. math::
|
106
|
+
|
107
|
+
e(q) = c(q) - c^*
|
108
|
+
|
109
|
+
Args:
|
110
|
+
configuration: Robot configuration :math:`q`.
|
111
|
+
|
112
|
+
Returns:
|
113
|
+
Center-of-mass task error vector :math:`e(q)`.
|
114
|
+
"""
|
115
|
+
if self.target_com is None:
|
116
|
+
raise TargetNotSet(self.__class__.__name__)
|
117
|
+
# Note: body 0 is the world body, so we start from body 1 (the robot).
|
118
|
+
# TODO(kevin): Don't hardcode subtree index.
|
119
|
+
return configuration.data.subtree_com[1] - self.target_com
|
120
|
+
|
121
|
+
def compute_jacobian(self, configuration: Configuration) -> np.ndarray:
|
122
|
+
r"""Compute the Jacobian of the CoM task error :math:`e(q)`.
|
123
|
+
|
124
|
+
The Jacobian is the derivative of this error with respect to the
|
125
|
+
generalized coordinates :math:`q`. Since the target :math:`c^*` is
|
126
|
+
constant, the Jacobian of the error simplifies to the Jacobian of the
|
127
|
+
CoM position :math:`c(q)`:
|
128
|
+
|
129
|
+
.. math::
|
130
|
+
|
131
|
+
J(q) = \frac{\partial e(q)}{\partial q} = \frac{\partial c(q)}{\partial q}
|
132
|
+
|
133
|
+
MuJoCo's ``mj_jacSubtreeCom`` function computes this Jacobian using the
|
134
|
+
formula:
|
135
|
+
|
136
|
+
.. math::
|
137
|
+
|
138
|
+
\frac{\partial c(q)}{\partial q} =
|
139
|
+
\frac{1}{M} \sum_{i \in \mathcal{B}} m_i \frac{\partial p_i(q)}{\partial q}
|
140
|
+
= \frac{1}{M} \sum_{i \in \mathcal{B}} m_i J_i(q)
|
141
|
+
|
142
|
+
where :math:`M = \sum_{i \in \mathcal{B}} m_i` is the total mass of the subtree,
|
143
|
+
:math:`m_i` is the mass of body :math:`i`, :math:`p_i(q)` is the position
|
144
|
+
of the origin of body frame :math:`i` in the world frame, :math:`J_i(q) =
|
145
|
+
\frac{\partial p_i(q)}{\partial q}` is the Jacobian mapping joint velocities to
|
146
|
+
the linear velocity of the origin of body frame :math:`i`, and the sum is over
|
147
|
+
all bodies :math:`\mathcal{B}` in the specified subtree (body 1 and its
|
148
|
+
descendants).
|
149
|
+
|
150
|
+
Args:
|
151
|
+
configuration: Robot configuration :math:`q`.
|
152
|
+
|
153
|
+
Returns:
|
154
|
+
Jacobian of the center-of-mass task error :math:`J(q)`.
|
155
|
+
"""
|
156
|
+
# NOTE: We don't need a target CoM to compute this Jacobian.
|
157
|
+
jac = np.empty((self.k, configuration.nv))
|
158
|
+
mujoco.mj_jacSubtreeCom(configuration.model, configuration.data, jac, 1)
|
159
|
+
return jac
|