jaxsim 0.7.1.dev49__tar.gz → 0.7.1.dev53__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.
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/PKG-INFO +1 -1
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/examples/assets/cartpole.urdf +12 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/_version.py +2 -2
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/api/contact.py +39 -23
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/api/kin_dyn_parameters.py +97 -1
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/api/model.py +22 -1
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/math/rotation.py +14 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/mujoco/loaders.py +28 -1
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/rbda/__init__.py +6 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/rbda/contacts/common.py +17 -11
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/rbda/contacts/relaxed_rigid.py +125 -16
- jaxsim-0.7.1.dev53/src/jaxsim/rbda/kinematic_constraints.py +148 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim.egg-info/PKG-INFO +1 -1
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim.egg-info/SOURCES.txt +3 -1
- jaxsim-0.7.1.dev53/tests/assets/double_pendulum.sdf +172 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/tests/conftest.py +47 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/tests/test_simulations.py +143 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/.devcontainer/Dockerfile +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/.devcontainer/devcontainer.json +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/.gitattributes +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/.github/CODEOWNERS +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/.github/dependabot.yml +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/.github/release.yml +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/.github/workflows/ci_cd.yml +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/.github/workflows/gpu_benchmark.yml +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/.github/workflows/pixi.yml +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/.github/workflows/read_the_docs.yml +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/.gitignore +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/.pre-commit-config.yaml +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/.readthedocs.yaml +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/CONTRIBUTING.md +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/LICENSE +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/README.md +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/docs/Makefile +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/docs/conf.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/docs/examples.rst +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/docs/guide/configuration.rst +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/docs/guide/install.rst +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/docs/index.rst +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/docs/make.bat +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/docs/modules/api.rst +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/docs/modules/math.rst +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/docs/modules/mujoco.rst +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/docs/modules/parsers.rst +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/docs/modules/rbda.rst +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/docs/modules/typing.rst +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/docs/modules/utils.rst +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/environment.yml +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/examples/.gitattributes +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/examples/.gitignore +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/examples/README.md +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/examples/assets/build_cartpole_urdf.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/examples/jaxsim_as_multibody_dynamics_library.ipynb +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/examples/jaxsim_as_physics_engine.ipynb +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/examples/jaxsim_as_physics_engine_advanced.ipynb +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/examples/jaxsim_for_robot_controllers.ipynb +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/pixi.lock +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/pyproject.toml +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/setup.cfg +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/__init__.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/api/__init__.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/api/actuation_model.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/api/com.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/api/common.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/api/data.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/api/frame.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/api/integrators.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/api/joint.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/api/link.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/api/ode.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/api/references.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/exceptions.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/logging.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/math/__init__.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/math/adjoint.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/math/cross.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/math/inertia.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/math/joint_model.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/math/quaternion.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/math/skew.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/math/transform.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/math/utils.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/mujoco/__init__.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/mujoco/__main__.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/mujoco/model.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/mujoco/utils.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/mujoco/visualizer.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/parsers/__init__.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/parsers/descriptions/__init__.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/parsers/descriptions/collision.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/parsers/descriptions/joint.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/parsers/descriptions/link.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/parsers/descriptions/model.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/parsers/kinematic_graph.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/parsers/rod/__init__.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/parsers/rod/meshes.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/parsers/rod/parser.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/parsers/rod/utils.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/rbda/aba.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/rbda/actuation/__init__.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/rbda/actuation/common.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/rbda/collidable_points.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/rbda/contacts/__init__.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/rbda/contacts/rigid.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/rbda/contacts/soft.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/rbda/crba.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/rbda/forward_kinematics.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/rbda/jacobian.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/rbda/rnea.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/rbda/utils.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/terrain/__init__.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/terrain/terrain.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/typing.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/utils/__init__.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/utils/jaxsim_dataclass.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/utils/tracing.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim/utils/wrappers.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim.egg-info/dependency_links.txt +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim.egg-info/requires.txt +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/src/jaxsim.egg-info/top_level.txt +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/tests/__init__.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/tests/test_actuation.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/tests/test_api_com.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/tests/test_api_contact.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/tests/test_api_data.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/tests/test_api_frame.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/tests/test_api_joint.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/tests/test_api_link.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/tests/test_api_model.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/tests/test_api_model_hw_parametrization.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/tests/test_automatic_differentiation.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/tests/test_benchmark.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/tests/test_exceptions.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/tests/test_meshes.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/tests/test_pytree.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/tests/test_visualizer.py +0 -0
- {jaxsim-0.7.1.dev49 → jaxsim-0.7.1.dev53}/tests/utils_idyntree.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: jaxsim
|
3
|
-
Version: 0.7.1.
|
3
|
+
Version: 0.7.1.dev53
|
4
4
|
Summary: A differentiable physics engine and multibody dynamics library for control and robot learning.
|
5
5
|
Author-email: Diego Ferigo <dgferigo@gmail.com>, Filippo Luca Ferretti <filippoluca.ferretti@outlook.com>
|
6
6
|
Maintainer-email: Filippo Luca Ferretti <filippo.ferretti@iit.it>, Alessandro Croci <alessandro.croci@iit.it>
|
@@ -58,6 +58,18 @@
|
|
58
58
|
</geometry>
|
59
59
|
</collision>
|
60
60
|
</link>
|
61
|
+
<link name="cart_frame"/>
|
62
|
+
<link name="rail_frame"/>
|
63
|
+
<joint name="cart_frame_joint" type="fixed">
|
64
|
+
<parent link="cart" />
|
65
|
+
<child link="cart_frame" />
|
66
|
+
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" />
|
67
|
+
</joint>
|
68
|
+
<joint name="rail_frame_joint" type="fixed">
|
69
|
+
<parent link="rail" />
|
70
|
+
<child link="rail_frame" />
|
71
|
+
<origin xyz="0.0 0.0 1.2" rpy="0.0 0.0 0.0" />
|
72
|
+
</joint>
|
61
73
|
<joint name="world_to_rail" type="fixed">
|
62
74
|
<origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0"/>
|
63
75
|
<parent link="world"/>
|
@@ -17,5 +17,5 @@ __version__: str
|
|
17
17
|
__version_tuple__: VERSION_TUPLE
|
18
18
|
version_tuple: VERSION_TUPLE
|
19
19
|
|
20
|
-
__version__ = version = '0.7.1.
|
21
|
-
__version_tuple__ = version_tuple = (0, 7, 1, '
|
20
|
+
__version__ = version = '0.7.1.dev53'
|
21
|
+
__version_tuple__ = version_tuple = (0, 7, 1, 'dev53')
|
@@ -191,39 +191,22 @@ def estimate_good_contact_parameters(
|
|
191
191
|
The user is encouraged to fine-tune the parameters based on the
|
192
192
|
specific application.
|
193
193
|
"""
|
194
|
-
|
195
|
-
|
196
|
-
"""
|
197
|
-
Displacement between the CoM and the lowest collidable point using zero
|
198
|
-
joint positions.
|
199
|
-
"""
|
200
|
-
|
201
|
-
zero_data = js.data.JaxSimModelData.build(
|
202
|
-
model=model,
|
203
|
-
)
|
204
|
-
|
194
|
+
if max_penetration is None:
|
195
|
+
zero_data = js.data.JaxSimModelData.build(model=model)
|
205
196
|
W_pz_CoM = js.com.com_position(model=model, data=zero_data)[2]
|
206
|
-
|
207
197
|
if model.floating_base():
|
208
198
|
W_pz_C = collidable_point_positions(model=model, data=zero_data)[:, -1]
|
209
|
-
|
210
|
-
|
211
|
-
return 2 * W_pz_CoM
|
199
|
+
W_pz_CoM = W_pz_CoM - W_pz_C.min()
|
212
200
|
|
213
|
-
|
214
|
-
max_penetration
|
215
|
-
if max_penetration is not None
|
216
|
-
# Consider as default a 0.5% of the model height.
|
217
|
-
else 0.005 * estimate_model_height(model=model)
|
218
|
-
)
|
201
|
+
# Consider as default a 1% of the model center of mass height.
|
202
|
+
max_penetration = 0.01 * W_pz_CoM
|
219
203
|
|
220
204
|
nc = number_of_active_collidable_points_steady_state
|
221
|
-
|
222
205
|
return model.contact_model._parameters_class().build_default_from_jaxsim_model(
|
223
206
|
model=model,
|
224
207
|
standard_gravity=standard_gravity,
|
225
208
|
static_friction_coefficient=static_friction_coefficient,
|
226
|
-
max_penetration=
|
209
|
+
max_penetration=max_penetration,
|
227
210
|
number_of_active_collidable_points_steady_state=nc,
|
228
211
|
damping_ratio=damping_ratio,
|
229
212
|
)
|
@@ -569,6 +552,39 @@ def link_contact_forces(
|
|
569
552
|
# to the frames associated to the collidable points.
|
570
553
|
W_f_L = link_forces_from_contact_forces(model=model, contact_forces=W_f_C)
|
571
554
|
|
555
|
+
# Process constraint wrenches if present.
|
556
|
+
if "constr_wrenches_inertial" in aux_dict:
|
557
|
+
wrench_pair_constr_inertial = aux_dict["constr_wrenches_inertial"]
|
558
|
+
|
559
|
+
# Retrieve the constraint map from the model's kinematic parameters.
|
560
|
+
constraint_map = model.kin_dyn_parameters.constraints
|
561
|
+
|
562
|
+
# Extract the frame indices of the constraints.
|
563
|
+
frame_idxs_1 = constraint_map.frame_idxs_1
|
564
|
+
frame_idxs_2 = constraint_map.frame_idxs_2
|
565
|
+
|
566
|
+
n_kin_constraints = frame_idxs_1.shape[0]
|
567
|
+
|
568
|
+
if n_kin_constraints > 0:
|
569
|
+
parent_link_indices = jax.vmap(
|
570
|
+
lambda frame_idx_1, frame_idx_2: jnp.array(
|
571
|
+
(
|
572
|
+
js.frame.idx_of_parent_link(model, frame_index=frame_idx_1),
|
573
|
+
js.frame.idx_of_parent_link(model, frame_index=frame_idx_2),
|
574
|
+
)
|
575
|
+
)
|
576
|
+
)(frame_idxs_1, frame_idxs_2)
|
577
|
+
|
578
|
+
# Apply each constraint wrench to its corresponding parent link in W_f_L.
|
579
|
+
def apply_wrench(W_f_L, parent_indices, wrench_pair):
|
580
|
+
W_f_L = W_f_L.at[parent_indices[0]].add(wrench_pair[0])
|
581
|
+
W_f_L = W_f_L.at[parent_indices[1]].add(wrench_pair[1])
|
582
|
+
return W_f_L
|
583
|
+
|
584
|
+
W_f_L = jax.vmap(apply_wrench, in_axes=(None, 0, 0))(
|
585
|
+
W_f_L, parent_link_indices, wrench_pair_constr_inertial
|
586
|
+
).sum(axis=0)
|
587
|
+
|
572
588
|
return W_f_L, aux_dict
|
573
589
|
|
574
590
|
|
@@ -34,6 +34,7 @@ class KinDynParameters(JaxsimDataclass):
|
|
34
34
|
joint_model: The joint model of the model.
|
35
35
|
joint_parameters: The parameters of the joints.
|
36
36
|
hw_link_metadata: The hardware parameters of the model links.
|
37
|
+
constraints: The kinematic constraints of the model. They can be used only with Relaxed-Rigid contact model.
|
37
38
|
"""
|
38
39
|
|
39
40
|
# Static
|
@@ -58,6 +59,9 @@ class KinDynParameters(JaxsimDataclass):
|
|
58
59
|
# Model hardware parameters
|
59
60
|
hw_link_metadata: HwLinkMetadata | None = dataclasses.field(default=None)
|
60
61
|
|
62
|
+
# Kinematic constraints
|
63
|
+
constraints: ConstraintMap | None = dataclasses.field(default=None)
|
64
|
+
|
61
65
|
@property
|
62
66
|
def motion_subspaces(self) -> jtp.Matrix:
|
63
67
|
r"""
|
@@ -80,12 +84,15 @@ class KinDynParameters(JaxsimDataclass):
|
|
80
84
|
return self._support_body_array_bool.get()
|
81
85
|
|
82
86
|
@staticmethod
|
83
|
-
def build(
|
87
|
+
def build(
|
88
|
+
model_description: ModelDescription, constraints: ConstraintMap | None
|
89
|
+
) -> KinDynParameters:
|
84
90
|
"""
|
85
91
|
Construct the kinematic and dynamic parameters of the model.
|
86
92
|
|
87
93
|
Args:
|
88
94
|
model_description: The parsed model description to consider.
|
95
|
+
constraints: An object of type ConstraintMap specifying the kinematic constraint of the model.
|
89
96
|
|
90
97
|
Returns:
|
91
98
|
The kinematic and dynamic parameters of the model.
|
@@ -253,6 +260,12 @@ class KinDynParameters(JaxsimDataclass):
|
|
253
260
|
|
254
261
|
motion_subspaces = jnp.vstack([jnp.zeros((6, 1))[jnp.newaxis, ...], S_J])
|
255
262
|
|
263
|
+
# ===========
|
264
|
+
# Constraints
|
265
|
+
# ===========
|
266
|
+
|
267
|
+
constraints = ConstraintMap() if constraints is None else constraints
|
268
|
+
|
256
269
|
# =================================
|
257
270
|
# Build and return KinDynParameters
|
258
271
|
# =================================
|
@@ -267,6 +280,7 @@ class KinDynParameters(JaxsimDataclass):
|
|
267
280
|
joint_parameters=joint_parameters,
|
268
281
|
contact_parameters=contact_parameters,
|
269
282
|
frame_parameters=frame_parameters,
|
283
|
+
constraints=constraints,
|
270
284
|
)
|
271
285
|
|
272
286
|
def __eq__(self, other: KinDynParameters) -> bool:
|
@@ -1168,3 +1182,85 @@ class ScalingFactors(JaxsimDataclass):
|
|
1168
1182
|
|
1169
1183
|
dims: jtp.Vector
|
1170
1184
|
density: jtp.Float
|
1185
|
+
|
1186
|
+
|
1187
|
+
@dataclasses.dataclass(frozen=True)
|
1188
|
+
class ConstraintType:
|
1189
|
+
"""
|
1190
|
+
Enumeration of all supported constraint types.
|
1191
|
+
"""
|
1192
|
+
|
1193
|
+
Weld: ClassVar[int] = 0
|
1194
|
+
# TODO: handle Connect constraint
|
1195
|
+
# Connect: ClassVar[int] = 1
|
1196
|
+
|
1197
|
+
|
1198
|
+
@jax_dataclasses.pytree_dataclass
|
1199
|
+
class ConstraintMap(JaxsimDataclass):
|
1200
|
+
"""
|
1201
|
+
Class storing the kinematic constraints of a model.
|
1202
|
+
"""
|
1203
|
+
|
1204
|
+
frame_idxs_1: jtp.Int = dataclasses.field(
|
1205
|
+
default_factory=lambda: jnp.array([], dtype=int)
|
1206
|
+
)
|
1207
|
+
frame_idxs_2: jtp.Int = dataclasses.field(
|
1208
|
+
default_factory=lambda: jnp.array([], dtype=int)
|
1209
|
+
)
|
1210
|
+
constraint_types: jtp.Int = dataclasses.field(
|
1211
|
+
default_factory=lambda: jnp.array([], dtype=int)
|
1212
|
+
)
|
1213
|
+
K_P: jtp.Float = dataclasses.field(
|
1214
|
+
default_factory=lambda: jnp.array([], dtype=float)
|
1215
|
+
)
|
1216
|
+
K_D: jtp.Float = dataclasses.field(
|
1217
|
+
default_factory=lambda: jnp.array([], dtype=float)
|
1218
|
+
)
|
1219
|
+
|
1220
|
+
def add_constraint(
|
1221
|
+
self,
|
1222
|
+
frame_idx_1: int,
|
1223
|
+
frame_idx_2: int,
|
1224
|
+
constraint_type: int,
|
1225
|
+
K_P: float | None = None,
|
1226
|
+
K_D: float | None = None,
|
1227
|
+
) -> ConstraintMap:
|
1228
|
+
"""
|
1229
|
+
Add a constraint to the constraint map.
|
1230
|
+
|
1231
|
+
Args:
|
1232
|
+
frame_idx_1: The index of the first frame.
|
1233
|
+
frame_idx_2: The index of the second frame.
|
1234
|
+
constraint_type: The type of constraint.
|
1235
|
+
K_P: The proportional gain for Baumgarte stabilization (default: 1000).
|
1236
|
+
K_D: The derivative gain for Baumgarte stabilization (default: 2 * sqrt(K_P)).
|
1237
|
+
|
1238
|
+
Returns:
|
1239
|
+
A new ConstraintMap instance with the added constraint.
|
1240
|
+
|
1241
|
+
Note:
|
1242
|
+
Since this method returns a new instance of ConstraintMap with the new constraint,
|
1243
|
+
it will trigger recompilations in JIT-compiled functions.
|
1244
|
+
"""
|
1245
|
+
|
1246
|
+
# Set default values for Baumgarte coefficients if not provided
|
1247
|
+
if K_P is None:
|
1248
|
+
K_P = 1000
|
1249
|
+
if K_D is None:
|
1250
|
+
K_D = 2 * np.sqrt(K_P)
|
1251
|
+
|
1252
|
+
# Create new arrays with the input elements appended
|
1253
|
+
new_frame_idxs_1 = jnp.append(self.frame_idxs_1, frame_idx_1)
|
1254
|
+
new_frame_idxs2 = jnp.append(self.frame_idxs_2, frame_idx_2)
|
1255
|
+
new_constraint_types = jnp.append(self.constraint_types, constraint_type)
|
1256
|
+
new_K_P = jnp.append(self.K_P, K_P)
|
1257
|
+
new_K_D = jnp.append(self.K_D, K_D)
|
1258
|
+
|
1259
|
+
# Return a new ConstraintMap object with updated attributes
|
1260
|
+
return ConstraintMap(
|
1261
|
+
frame_idxs_1=new_frame_idxs_1,
|
1262
|
+
frame_idxs_2=new_frame_idxs2,
|
1263
|
+
constraint_types=new_constraint_types,
|
1264
|
+
K_P=new_K_P,
|
1265
|
+
K_D=new_K_D,
|
1266
|
+
)
|
@@ -141,6 +141,7 @@ class JaxSimModel(JaxsimDataclass):
|
|
141
141
|
is_urdf: bool | None = None,
|
142
142
|
considered_joints: Sequence[str] | None = None,
|
143
143
|
gravity: jtp.FloatLike = jaxsim.math.STANDARD_GRAVITY,
|
144
|
+
constraints: jaxsim.rbda.kinematic_constraints.ConstraintMap | None = None,
|
144
145
|
) -> JaxSimModel:
|
145
146
|
"""
|
146
147
|
Build a Model object from a model description.
|
@@ -167,6 +168,9 @@ class JaxSimModel(JaxsimDataclass):
|
|
167
168
|
considered_joints:
|
168
169
|
The list of joints to consider. If None, all joints are considered.
|
169
170
|
gravity: The gravity constant. Normally passed as a positive value.
|
171
|
+
constraints:
|
172
|
+
An object of type ConstraintMap containing the kinematic constraints to consider. If None, no constraints are considered.
|
173
|
+
Note that constraints can be used only with RelaxedRigidContacts.
|
170
174
|
|
171
175
|
Returns:
|
172
176
|
The built Model object.
|
@@ -198,6 +202,7 @@ class JaxSimModel(JaxsimDataclass):
|
|
198
202
|
contact_params=contact_params,
|
199
203
|
integrator=integrator,
|
200
204
|
gravity=-gravity,
|
205
|
+
constraints=constraints,
|
201
206
|
)
|
202
207
|
|
203
208
|
# Store the origin of the model, in case downstream logic needs it.
|
@@ -225,6 +230,7 @@ class JaxSimModel(JaxsimDataclass):
|
|
225
230
|
actuation_params: jaxsim.rbda.actuation.ActuationParams | None = None,
|
226
231
|
integrator: IntegratorType | None = None,
|
227
232
|
gravity: jtp.FloatLike = jaxsim.math.STANDARD_GRAVITY,
|
233
|
+
constraints: jaxsim.rbda.kinematic_constraints.ConstraintMap | None = None,
|
228
234
|
) -> JaxSimModel:
|
229
235
|
"""
|
230
236
|
Build a Model object from an intermediate model description.
|
@@ -247,6 +253,8 @@ class JaxSimModel(JaxsimDataclass):
|
|
247
253
|
actuation_params: The parameters of the actuation model.
|
248
254
|
integrator: The integrator to use for the simulation.
|
249
255
|
gravity: The gravity constant.
|
256
|
+
constraints:
|
257
|
+
An object of type ConstraintMap containing the kinematic constraints to consider. If None, no constraints are considered.
|
250
258
|
|
251
259
|
Returns:
|
252
260
|
The built Model object.
|
@@ -278,6 +286,14 @@ class JaxSimModel(JaxsimDataclass):
|
|
278
286
|
else jaxsim.rbda.contacts.RelaxedRigidContacts.build()
|
279
287
|
)
|
280
288
|
|
289
|
+
if constraints is not None and not isinstance(
|
290
|
+
contact_model, jaxsim.rbda.contacts.RelaxedRigidContacts
|
291
|
+
):
|
292
|
+
constraints = None
|
293
|
+
logging.warning(
|
294
|
+
f"Contact model {contact_model.__class__.__name__} does not support kinematic constraints. Use RelaxedRigidContacts instead."
|
295
|
+
)
|
296
|
+
|
281
297
|
if contact_params is None:
|
282
298
|
contact_params = contact_model._parameters_class()
|
283
299
|
|
@@ -295,7 +311,7 @@ class JaxSimModel(JaxsimDataclass):
|
|
295
311
|
model = cls(
|
296
312
|
model_name=model_name,
|
297
313
|
kin_dyn_parameters=js.kin_dyn_parameters.KinDynParameters.build(
|
298
|
-
model_description=model_description
|
314
|
+
model_description=model_description, constraints=constraints
|
299
315
|
),
|
300
316
|
time_step=time_step,
|
301
317
|
terrain=terrain,
|
@@ -777,6 +793,7 @@ def reduce(
|
|
777
793
|
actuation_params=model.actuation_params,
|
778
794
|
gravity=model.gravity,
|
779
795
|
integrator=model.integrator,
|
796
|
+
constraints=model.kin_dyn_parameters.constraints,
|
780
797
|
)
|
781
798
|
|
782
799
|
with reduced_model.mutable_context(mutability=Mutability.MUTABLE_NO_VALIDATION):
|
@@ -2330,7 +2347,11 @@ def update_hw_parameters(
|
|
2330
2347
|
|
2331
2348
|
Returns:
|
2332
2349
|
The updated JaxSimModel object with modified hardware parameters.
|
2350
|
+
|
2351
|
+
Note:
|
2352
|
+
This function can be used only with models using Relax-Rigid contact model.
|
2333
2353
|
"""
|
2354
|
+
|
2334
2355
|
kin_dyn_params: KinDynParameters = model.kin_dyn_parameters
|
2335
2356
|
link_parameters: LinkParameters = kin_dyn_params.link_parameters
|
2336
2357
|
hw_link_metadata: HwLinkMetadata = kin_dyn_params.hw_link_metadata
|
@@ -82,3 +82,17 @@ class Rotation:
|
|
82
82
|
R = c * jnp.eye(3) - s * Skew.wedge(u) + c1 * u @ u.T
|
83
83
|
|
84
84
|
return R.transpose()
|
85
|
+
|
86
|
+
@staticmethod
|
87
|
+
def log_vee(R: jnp.ndarray) -> jtp.Vector:
|
88
|
+
"""
|
89
|
+
Compute the logarithm map of an SO(3) rotation matrix.
|
90
|
+
|
91
|
+
Args:
|
92
|
+
R: The SO(3) rotation matrix.
|
93
|
+
|
94
|
+
Returns:
|
95
|
+
The corresponding so(3) tangent vector.
|
96
|
+
"""
|
97
|
+
|
98
|
+
return jaxlie.SO3.from_matrix(R).log()
|
@@ -5,6 +5,7 @@ import warnings
|
|
5
5
|
from collections.abc import Sequence
|
6
6
|
from typing import Any
|
7
7
|
|
8
|
+
import jaxlie
|
8
9
|
import mujoco as mj
|
9
10
|
import numpy as np
|
10
11
|
import rod.urdf.exporter
|
@@ -279,11 +280,13 @@ class RodModelToMjcf:
|
|
279
280
|
# Add a floating joint if floating-base
|
280
281
|
# -------------------------------------
|
281
282
|
|
283
|
+
base_link_name = rod_model.get_canonical_link()
|
284
|
+
|
282
285
|
if not rod_model.is_fixed_base():
|
283
286
|
considered_joints |= {"world_to_base"}
|
284
287
|
urdf_string = RodModelToMjcf.add_floating_joint(
|
285
288
|
urdf_string=urdf_string,
|
286
|
-
base_link_name=
|
289
|
+
base_link_name=base_link_name,
|
287
290
|
floating_joint_name="world_to_base",
|
288
291
|
)
|
289
292
|
|
@@ -379,6 +382,30 @@ class RodModelToMjcf:
|
|
379
382
|
# Find the <mujoco> element (might be the root itself).
|
380
383
|
mujoco_element: ET._Element = next(iter(root.iter("mujoco")))
|
381
384
|
|
385
|
+
# --------------
|
386
|
+
# Add the frames
|
387
|
+
# --------------
|
388
|
+
|
389
|
+
for frame in rod_model.frames():
|
390
|
+
frame: rod.Frame
|
391
|
+
parent_name = frame.attached_to
|
392
|
+
parent_element = mujoco_element.find(f".//body[@name='{parent_name}']")
|
393
|
+
|
394
|
+
if parent_element is None and parent_name == base_link_name:
|
395
|
+
parent_element = mujoco_element.find(".//worldbody")
|
396
|
+
|
397
|
+
if parent_element is not None:
|
398
|
+
quat = jaxlie.SO3.from_rpy_radians(*frame.pose.rpy).wxyz
|
399
|
+
_ = ET.SubElement(
|
400
|
+
parent_element,
|
401
|
+
"site",
|
402
|
+
name=frame.name,
|
403
|
+
pos=" ".join(map(str, frame.pose.xyz)),
|
404
|
+
quat=" ".join(map(str, quat)),
|
405
|
+
)
|
406
|
+
else:
|
407
|
+
warnings.warn(f"Parent link '{parent_name}' not found", stacklevel=2)
|
408
|
+
|
382
409
|
# --------------
|
383
410
|
# Add the motors
|
384
411
|
# --------------
|
@@ -8,4 +8,10 @@ from .jacobian import (
|
|
8
8
|
jacobian_derivative_full_doubly_left,
|
9
9
|
jacobian_full_doubly_left,
|
10
10
|
)
|
11
|
+
from .kinematic_constraints import (
|
12
|
+
compute_constraint_baumgarte_term,
|
13
|
+
compute_constraint_jacobians,
|
14
|
+
compute_constraint_jacobians_derivative,
|
15
|
+
compute_constraint_transforms,
|
16
|
+
)
|
11
17
|
from .rnea import rnea
|
@@ -18,6 +18,10 @@ except ImportError:
|
|
18
18
|
from typing_extensions import Self
|
19
19
|
|
20
20
|
|
21
|
+
MAX_STIFFNESS = 1e6
|
22
|
+
MAX_DAMPING = 1e4
|
23
|
+
|
24
|
+
|
21
25
|
@functools.partial(jax.jit, static_argnames=("terrain",))
|
22
26
|
def compute_penetration_data(
|
23
27
|
p: jtp.VectorLike,
|
@@ -133,28 +137,30 @@ class ContactsParams(JaxsimDataclass):
|
|
133
137
|
ξ = damping_ratio
|
134
138
|
δ_max = max_penetration
|
135
139
|
μc = static_friction_coefficient
|
140
|
+
nc = number_of_active_collidable_points_steady_state
|
136
141
|
|
137
142
|
# Compute the total mass of the model.
|
138
143
|
m = jnp.array(model.kin_dyn_parameters.link_parameters.mass).sum()
|
139
144
|
|
140
|
-
# Rename the standard gravity.
|
141
|
-
g = standard_gravity
|
142
|
-
|
143
|
-
# Compute the average support force on each collidable point.
|
144
|
-
f_average = m * g / number_of_active_collidable_points_steady_state
|
145
|
-
|
146
145
|
# Compute the stiffness to get the desired steady-state penetration.
|
147
146
|
# Note that this is dependent on the non-linear exponent used in
|
148
147
|
# the damping term of the Hunt/Crossley model.
|
149
|
-
|
148
|
+
if stiffness is None:
|
149
|
+
# Compute the average support force on each collidable point.
|
150
|
+
f_average = m * standard_gravity / nc
|
151
|
+
|
152
|
+
stiffness = f_average / jnp.power(δ_max, 1 + p)
|
153
|
+
stiffness = jnp.clip(stiffness, 0, MAX_STIFFNESS)
|
150
154
|
|
151
155
|
# Compute the damping using the damping ratio.
|
152
|
-
critical_damping = 2 * jnp.sqrt(
|
153
|
-
|
156
|
+
critical_damping = 2 * jnp.sqrt(stiffness * m)
|
157
|
+
if damping is None:
|
158
|
+
damping = ξ * critical_damping
|
159
|
+
damping = jnp.clip(damping, 0, MAX_DAMPING)
|
154
160
|
|
155
161
|
return self.build(
|
156
|
-
K=
|
157
|
-
D=
|
162
|
+
K=stiffness,
|
163
|
+
D=damping,
|
158
164
|
mu=μc,
|
159
165
|
p=p,
|
160
166
|
q=q,
|