jaxsim 0.2.dev394__py3-none-any.whl → 0.2.dev423__py3-none-any.whl

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/_version.py CHANGED
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.2.dev394'
16
- __version_tuple__ = version_tuple = (0, 2, 'dev394')
15
+ __version__ = version = '0.2.dev423'
16
+ __version_tuple__ = version_tuple = (0, 2, 'dev423')
jaxsim/api/model.py CHANGED
@@ -986,8 +986,8 @@ def free_floating_gravity_forces(
986
986
  def free_floating_bias_forces(
987
987
  model: JaxSimModel, data: js.data.JaxSimModelData
988
988
  ) -> jtp.Vector:
989
- """
990
- Compute the free-floating bias forces :math:`h(\\mathbf{q}, \boldsymbol{\nu})`
989
+ r"""
990
+ Compute the free-floating bias forces :math:`h(\mathbf{q}, \boldsymbol{\nu})`
991
991
  of the model.
992
992
 
993
993
  Args:
jaxsim/mujoco/loaders.py CHANGED
@@ -13,7 +13,17 @@ def load_rod_model(
13
13
  is_urdf: bool | None = None,
14
14
  model_name: str | None = None,
15
15
  ) -> rod.Model:
16
- """"""
16
+ """
17
+ Loads a ROD model from a URDF/SDF file or a ROD model.
18
+
19
+ Args:
20
+ model_description: The URDF/SDF file or ROD model to load.
21
+ is_urdf: Whether the model description is a URDF file.
22
+ model_name: The name of the model to load from the resource.
23
+
24
+ Returns:
25
+ rod.Model: The loaded ROD model.
26
+ """
17
27
 
18
28
  # Parse the SDF resource.
19
29
  sdf_element = rod.Sdf.load(sdf=model_description, is_urdf=is_urdf)
@@ -50,7 +60,15 @@ class RodModelToMjcf:
50
60
  def assets_from_rod_model(
51
61
  rod_model: rod.Model,
52
62
  ) -> dict[str, bytes]:
53
- """"""
63
+ """
64
+ Generates a dictionary of assets from a ROD model.
65
+
66
+ Args:
67
+ rod_model: The ROD model to extract the assets from.
68
+
69
+ Returns:
70
+ dict: A dictionary of assets.
71
+ """
54
72
 
55
73
  import resolve_robotics_uri_py
56
74
 
@@ -85,7 +103,17 @@ class RodModelToMjcf:
85
103
  base_link_name: str,
86
104
  floating_joint_name: str = "world_to_base",
87
105
  ) -> str:
88
- """"""
106
+ """
107
+ Adds a floating joint to a URDF string.
108
+
109
+ Args:
110
+ urdf_string: The URDF string to modify.
111
+ base_link_name: The name of the base link to attach the floating joint.
112
+ floating_joint_name: The name of the floating joint to add.
113
+
114
+ Returns:
115
+ str: The modified URDF string.
116
+ """
89
117
 
90
118
  with tempfile.NamedTemporaryFile(mode="w+", suffix=".urdf") as urdf_file:
91
119
 
@@ -132,7 +160,16 @@ class RodModelToMjcf:
132
160
  plane_normal: tuple[float, float, float] = (0, 0, 1),
133
161
  heightmap: bool | None = None,
134
162
  ) -> tuple[str, dict[str, Any]]:
135
- """"""
163
+ """
164
+ Converts a ROD model to a Mujoco MJCF string.
165
+
166
+ Args:
167
+ rod_model: The ROD model to convert.
168
+ considered_joints: The list of joint names to consider in the conversion.
169
+
170
+ Returns:
171
+ tuple: A tuple containing the MJCF string and the assets dictionary.
172
+ """
136
173
 
137
174
  # -------------------------------------
138
175
  # Convert the model description to URDF
@@ -468,7 +505,17 @@ class UrdfToMjcf:
468
505
  plane_normal: tuple[float, float, float] = (0, 0, 1),
469
506
  heightmap: bool | None = None,
470
507
  ) -> tuple[str, dict[str, Any]]:
471
- """"""
508
+ """
509
+ Converts a URDF file to a Mujoco MJCF string.
510
+
511
+ Args:
512
+ urdf: The URDF file to convert.
513
+ considered_joints: The list of joint names to consider in the conversion.
514
+ model_name: The name of the model to convert.
515
+
516
+ Returns:
517
+ tuple: A tuple containing the MJCF string and the assets dictionary.
518
+ """
472
519
 
473
520
  # Get the ROD model.
474
521
  rod_model = load_rod_model(
@@ -495,7 +542,17 @@ class SdfToMjcf:
495
542
  plane_normal: tuple[float, float, float] = (0, 0, 1),
496
543
  heightmap: bool | None = None,
497
544
  ) -> tuple[str, dict[str, Any]]:
498
- """"""
545
+ """
546
+ Converts a SDF file to a Mujoco MJCF string.
547
+
548
+ Args:
549
+ sdf: The SDF file to convert.
550
+ considered_joints: The list of joint names to consider in the conversion.
551
+ model_name: The name of the model to convert.
552
+
553
+ Returns:
554
+ tuple: A tuple containing the MJCF string and the assets dictionary.
555
+ """
499
556
 
500
557
  # Get the ROD model.
501
558
  rod_model = load_rod_model(
jaxsim/mujoco/model.py CHANGED
@@ -1,3 +1,5 @@
1
+ from __future__ import annotations
2
+
1
3
  import functools
2
4
  import pathlib
3
5
  from typing import Any, Callable
@@ -18,7 +20,13 @@ class MujocoModelHelper:
18
20
  """
19
21
 
20
22
  def __init__(self, model: mj.MjModel, data: mj.MjData | None = None) -> None:
21
- """"""
23
+ """
24
+ Initialize the MujocoModelHelper object.
25
+
26
+ Args:
27
+ model: A Mujoco model object.
28
+ data: A Mujoco data object. If None, a new one will be created.
29
+ """
22
30
 
23
31
  self.model = model
24
32
  self.data = data if data is not None else mj.MjData(self.model)
@@ -34,8 +42,19 @@ class MujocoModelHelper:
34
42
  mjcf_description: str | pathlib.Path,
35
43
  assets: dict[str, Any] = None,
36
44
  heightmap: HeightmapCallable | None = None,
37
- ) -> "MujocoModelHelper":
38
- """"""
45
+ ) -> MujocoModelHelper:
46
+ """
47
+ Build a Mujoco model from an XML description and an optional assets dictionary.
48
+
49
+ Args:
50
+ mjcf_description: A string containing the XML description of the Mujoco model
51
+ or a path to a file containing the XML description.
52
+ assets: An optional dictionary containing the assets of the model.
53
+ heightmap: A function in two variables that returns the height of a terrain
54
+ in the specified coordinate point.
55
+ Returns:
56
+ A MujocoModelHelper object.
57
+ """
39
58
 
40
59
  # Read the XML description if it's a path to file
41
60
  mjcf_description = (
@@ -175,17 +194,17 @@ class MujocoModelHelper:
175
194
  # ==================
176
195
 
177
196
  def number_of_joints(self) -> int:
178
- """"""
197
+ """Returns the number of joints in the model."""
179
198
 
180
199
  return self.model.njnt
181
200
 
182
201
  def number_of_dofs(self) -> int:
183
- """"""
202
+ """Returns the number of DoFs in the model."""
184
203
 
185
204
  return self.model.nq
186
205
 
187
206
  def joint_names(self) -> list[str]:
188
- """"""
207
+ """Returns the names of the joints in the model."""
189
208
 
190
209
  return [
191
210
  mj.mj_id2name(self.model, mj.mjtObj.mjOBJ_JOINT, idx)
@@ -193,7 +212,7 @@ class MujocoModelHelper:
193
212
  ]
194
213
 
195
214
  def joint_dofs(self, joint_name: str) -> int:
196
- """"""
215
+ """Returns the number of DoFs of a joint."""
197
216
 
198
217
  if joint_name not in self.joint_names():
199
218
  raise ValueError(f"Joint '{joint_name}' not found")
@@ -201,7 +220,7 @@ class MujocoModelHelper:
201
220
  return self.data.joint(joint_name).qpos.size
202
221
 
203
222
  def joint_position(self, joint_name: str) -> npt.NDArray:
204
- """"""
223
+ """Returns the position of a joint."""
205
224
 
206
225
  if joint_name not in self.joint_names():
207
226
  raise ValueError(f"Joint '{joint_name}' not found")
@@ -209,7 +228,7 @@ class MujocoModelHelper:
209
228
  return self.data.joint(joint_name).qpos
210
229
 
211
230
  def joint_positions(self, joint_names: list[str] | None = None) -> npt.NDArray:
212
- """"""
231
+ """Returns the positions of the joints."""
213
232
 
214
233
  joint_names = joint_names if joint_names is not None else self.joint_names()
215
234
 
@@ -220,7 +239,7 @@ class MujocoModelHelper:
220
239
  def set_joint_position(
221
240
  self, joint_name: str, position: npt.NDArray | float
222
241
  ) -> None:
223
- """"""
242
+ """Sets the position of a joint."""
224
243
 
225
244
  position = np.atleast_1d(np.array(position).squeeze())
226
245
 
@@ -239,7 +258,7 @@ class MujocoModelHelper:
239
258
  def set_joint_positions(
240
259
  self, joint_names: list[str], positions: npt.NDArray | list[npt.NDArray]
241
260
  ) -> None:
242
- """"""
261
+ """Set the positions of multiple joints."""
243
262
 
244
263
  mask = self.mask_qpos(joint_names=tuple(joint_names))
245
264
  self.data.qpos[mask] = positions
@@ -249,12 +268,12 @@ class MujocoModelHelper:
249
268
  # ==================
250
269
 
251
270
  def number_of_bodies(self) -> int:
252
- """"""
271
+ """Returns the number of bodies in the model."""
253
272
 
254
273
  return self.model.nbody
255
274
 
256
275
  def body_names(self) -> list[str]:
257
- """"""
276
+ """Returns the names of the bodies in the model."""
258
277
 
259
278
  return [
260
279
  mj.mj_id2name(self.model, mj.mjtObj.mjOBJ_BODY, idx)
@@ -262,7 +281,7 @@ class MujocoModelHelper:
262
281
  ]
263
282
 
264
283
  def body_position(self, body_name: str) -> npt.NDArray:
265
- """"""
284
+ """Returns the position of a body."""
266
285
 
267
286
  if body_name not in self.body_names():
268
287
  raise ValueError(f"Body '{body_name}' not found")
@@ -270,7 +289,7 @@ class MujocoModelHelper:
270
289
  return self.data.body(body_name).xpos
271
290
 
272
291
  def body_orientation(self, body_name: str, dcm: bool = False) -> npt.NDArray:
273
- """"""
292
+ """Returns the orientation of a body."""
274
293
 
275
294
  if body_name not in self.body_names():
276
295
  raise ValueError(f"Body '{body_name}' not found")
@@ -284,12 +303,12 @@ class MujocoModelHelper:
284
303
  # ======================
285
304
 
286
305
  def number_of_geometries(self) -> int:
287
- """"""
306
+ """Returns the number of geometries in the model."""
288
307
 
289
308
  return self.model.ngeom
290
309
 
291
310
  def geometry_names(self) -> list[str]:
292
- """"""
311
+ """Returns the names of the geometries in the model."""
293
312
 
294
313
  return [
295
314
  mj.mj_id2name(self.model, mj.mjtObj.mjOBJ_GEOM, idx)
@@ -297,7 +316,7 @@ class MujocoModelHelper:
297
316
  ]
298
317
 
299
318
  def geometry_position(self, geometry_name: str) -> npt.NDArray:
300
- """"""
319
+ """Returns the position of a geometry."""
301
320
 
302
321
  if geometry_name not in self.geometry_names():
303
322
  raise ValueError(f"Geometry '{geometry_name}' not found")
@@ -307,7 +326,7 @@ class MujocoModelHelper:
307
326
  def geometry_orientation(
308
327
  self, geometry_name: str, dcm: bool = False
309
328
  ) -> npt.NDArray:
310
- """"""
329
+ """Returns the orientation of a geometry."""
311
330
 
312
331
  if geometry_name not in self.geometry_names():
313
332
  raise ValueError(f"Geometry '{geometry_name}' not found")
@@ -20,7 +20,17 @@ class MujocoVideoRecorder:
20
20
  height: int | None = None,
21
21
  **kwargs,
22
22
  ) -> None:
23
- """"""
23
+ """
24
+ Initialize the Mujoco video recorder.
25
+
26
+ Args:
27
+ model: The Mujoco model.
28
+ data: The Mujoco data.
29
+ fps: The frames per second.
30
+ width: The width of the video.
31
+ height: The height of the video.
32
+ **kwargs: Additional arguments for the renderer.
33
+ """
24
34
 
25
35
  width = width if width is not None else model.vis.global_.offwidth
26
36
  height = height if height is not None else model.vis.global_.offheight
@@ -45,7 +55,7 @@ class MujocoVideoRecorder:
45
55
  def reset(
46
56
  self, model: mj.MjModel | None = None, data: mj.MjData | None = None
47
57
  ) -> None:
48
- """"""
58
+ """Reset the model and data."""
49
59
 
50
60
  self.frames = []
51
61
 
@@ -53,7 +63,7 @@ class MujocoVideoRecorder:
53
63
  self.model = model if model is not None else self.model
54
64
 
55
65
  def render_frame(self, camera_name: str | None = None) -> npt.NDArray:
56
- """"""
66
+ """Renders a frame."""
57
67
  camera_name = camera_name or "track"
58
68
 
59
69
  mujoco.mj_forward(self.model, self.data)
@@ -62,14 +72,14 @@ class MujocoVideoRecorder:
62
72
  return self.renderer.render()
63
73
 
64
74
  def record_frame(self, camera_name: str | None = None) -> None:
65
- """"""
75
+ """Stores a frame in the buffer."""
66
76
  camera_name = camera_name or "track"
67
77
 
68
78
  frame = self.render_frame(camera_name=camera_name)
69
79
  self.frames.append(frame)
70
80
 
71
81
  def write_video(self, path: pathlib.Path, exist_ok: bool = False) -> None:
72
- """"""
82
+ """Writes the video to a file."""
73
83
 
74
84
  if path.is_dir():
75
85
  raise IsADirectoryError(f"The path '{path}' is a directory.")
@@ -110,7 +120,13 @@ class MujocoVisualizer:
110
120
  def __init__(
111
121
  self, model: mj.MjModel | None = None, data: mj.MjData | None = None
112
122
  ) -> None:
113
- """"""
123
+ """
124
+ Initialize the Mujoco visualizer.
125
+
126
+ Args:
127
+ model: The Mujoco model.
128
+ data: The Mujoco data.
129
+ """
114
130
 
115
131
  self.data = data
116
132
  self.model = model
@@ -121,7 +137,7 @@ class MujocoVisualizer:
121
137
  model: mj.MjModel | None = None,
122
138
  data: mj.MjData | None = None,
123
139
  ) -> None:
124
- """"""
140
+ """Updates the viewer with the current model and data."""
125
141
 
126
142
  data = data if data is not None else self.data
127
143
  model = model if model is not None else self.model
@@ -132,7 +148,7 @@ class MujocoVisualizer:
132
148
  def open_viewer(
133
149
  self, model: mj.MjModel | None = None, data: mj.MjData | None = None
134
150
  ) -> mj.viewer.Handle:
135
- """"""
151
+ """Opens a viewer."""
136
152
 
137
153
  data = data if data is not None else self.data
138
154
  model = model if model is not None else self.model
@@ -150,7 +166,7 @@ class MujocoVisualizer:
150
166
  data: mj.MjData | None = None,
151
167
  close_on_exit: bool = True,
152
168
  ) -> ContextManager[mujoco.viewer.Handle]:
153
- """"""
169
+ """Context manager to open a viewer."""
154
170
 
155
171
  handle = self.open_viewer(model=model, data=data)
156
172
 
@@ -1,6 +1,6 @@
1
1
  BSD 3-Clause License
2
2
 
3
- Copyright (c) 2022, Artificial and Mechanical Intelligence
3
+ Copyright (c) 2022, Artificial and Mechanical Intelligence
4
4
  All rights reserved.
5
5
 
6
6
  Redistribution and use in source and binary forms, with or without
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jaxsim
3
- Version: 0.2.dev394
3
+ Version: 0.2.dev423
4
4
  Summary: A physics engine in reduced coordinates implemented with JAX.
5
5
  Home-page: https://github.com/ami-iit/jaxsim
6
6
  Author: Diego Ferigo
@@ -39,7 +39,7 @@ Requires-Dist: pptree
39
39
  Requires-Dist: rod >=0.2.0
40
40
  Requires-Dist: typing-extensions ; python_version < "3.12"
41
41
  Provides-Extra: all
42
- Requires-Dist: black[jupyter] ; extra == 'all'
42
+ Requires-Dist: black[jupyter] ~=24.0 ; extra == 'all'
43
43
  Requires-Dist: isort ; extra == 'all'
44
44
  Requires-Dist: pre-commit ; extra == 'all'
45
45
  Requires-Dist: idyntree ; extra == 'all'
@@ -50,7 +50,7 @@ Requires-Dist: lxml ; extra == 'all'
50
50
  Requires-Dist: mediapy ; extra == 'all'
51
51
  Requires-Dist: mujoco >=3.0.0 ; extra == 'all'
52
52
  Provides-Extra: style
53
- Requires-Dist: black[jupyter] ; extra == 'style'
53
+ Requires-Dist: black[jupyter] ~=24.0 ; extra == 'style'
54
54
  Requires-Dist: isort ; extra == 'style'
55
55
  Requires-Dist: pre-commit ; extra == 'style'
56
56
  Provides-Extra: testing
@@ -1,5 +1,5 @@
1
1
  jaxsim/__init__.py,sha256=OcrfoYS1DGcmAGqu2AqlCTiUVxcpi-IsVwcr_16x74Q,1789
2
- jaxsim/_version.py,sha256=so5jZFKl8aDmZRylEyYqJKNNSSEg2aGlO-xfDv0En8w,423
2
+ jaxsim/_version.py,sha256=owkLWbz7fNKHUUsy4zTEkEjYtjYzRLHH7f2f09P3roY,423
3
3
  jaxsim/logging.py,sha256=c4zhwBKf9eAYAHVp62kTEllqdsZgh0K-kPKVy8L3elU,1584
4
4
  jaxsim/typing.py,sha256=MeuOCQtLAr-sPkvB_sU8FtwGNRirz1auCwIgRC-QZl8,646
5
5
  jaxsim/api/__init__.py,sha256=fNTCPUeDfOAizRd4RsW3Epv0sLTu0KJGoFRSEsi75VM,162
@@ -10,7 +10,7 @@ jaxsim/api/data.py,sha256=cPFy6TTm0rNpDk1O0ZxOpvBwWVPu6V14XLRMeC7x81Q,26786
10
10
  jaxsim/api/joint.py,sha256=q31Kp3Cqv-yTcxijjzbj_QADFnGQyjb2al9fYZtzedo,4763
11
11
  jaxsim/api/kin_dyn_parameters.py,sha256=G4mtSi8fElYe0yttLgsxSOPf7vcK-yqTu06Aa5SSrYg,26012
12
12
  jaxsim/api/link.py,sha256=rypTwkMf9HJ5UuAtHRJh0LqqdJWcLKTtTjWcjduEsF0,9842
13
- jaxsim/api/model.py,sha256=u7CZTNc0UY0ZVpUEW-RsZi2UysyzbK06zvSPsdOlPYQ,52269
13
+ jaxsim/api/model.py,sha256=UwjZctpQR_3F8_Cm-NmFQb14Wtw_vscs3Yg-ULpQyrs,52269
14
14
  jaxsim/api/ode.py,sha256=6l-6i2YHagsQvR8Ac-_fmO6P0hBVT6NkHhwXnrdITEg,9785
15
15
  jaxsim/api/ode_data.py,sha256=dwRFVPJ30XMmdUbPXEu7YxsQ97jZP4L4fd5ZzhrO5Ys,22184
16
16
  jaxsim/api/references.py,sha256=Lvskf17r619KKxwCJP7hAAty2kaXgDXJX1uKqoDIDgo,15483
@@ -29,9 +29,9 @@ jaxsim/math/skew.py,sha256=oOGSSR8PUGROl6IJFlrmu6K3gPH-u16hUPfKIkcVv9o,1177
29
29
  jaxsim/math/transform.py,sha256=boeuN8df4Yd9NvS64g-xUYoNqG91YafYLam4iITFJVg,2917
30
30
  jaxsim/mujoco/__init__.py,sha256=Zo5GAlN1DYKvX8s1hu1j6HntKIbBMLB9Puv9ouaNAZ8,158
31
31
  jaxsim/mujoco/__main__.py,sha256=GBmB7J-zj75ZnFyuAAmpSOpbxi_HhHhWJeot3ljGDJY,5291
32
- jaxsim/mujoco/loaders.py,sha256=PG6TrmurdF99B_HJW39daNXMYlwGy3JMofb4oTRwPLc,17406
33
- jaxsim/mujoco/model.py,sha256=ErL4X4QWPCJJJjCAMHsFsksYTgIpmV_M8xWPZc-gQcA,12117
34
- jaxsim/mujoco/visualizer.py,sha256=-qg26t5tleTva6zzQmc5SdnlC8XZ1ZAwZ_lDjdwHJ0A,4400
32
+ jaxsim/mujoco/loaders.py,sha256=FwEZHdRZoxOqXPauQUojP5mjknMaTb386V2BSiAoz5Q,19323
33
+ jaxsim/mujoco/model.py,sha256=5-4KTbEbU19zjrSuvUVdLo3noWxTvlCNsFIs3rQTNDY,13506
34
+ jaxsim/mujoco/visualizer.py,sha256=YlteqcCbeB1B6saAHKBz1IJad3N5Rp163reZrzKLAys,5065
35
35
  jaxsim/parsers/__init__.py,sha256=sonYi-bBWAoB04kp1mxT4uIORxjb7SdZ0ukGPmVx98Y,44
36
36
  jaxsim/parsers/kinematic_graph.py,sha256=_ZJr-u1m64qPCeY6BHTI56dSOWhOGfbg2HN49XbTXhA,23784
37
37
  jaxsim/parsers/descriptions/__init__.py,sha256=EbTfnrK3oCxA3pNv--YUwllJ6uICENvFgAdRbYtS9ts,238
@@ -57,8 +57,8 @@ jaxsim/utils/__init__.py,sha256=tnQq1_CavdfeKaLYt3pmO7Jk4MU2RwwQU_qICkjyoTY,197
57
57
  jaxsim/utils/hashless.py,sha256=bFIwKeo9KiWwsY8QM55duEGGQOyyJ4jQyPcuqTLEp5k,297
58
58
  jaxsim/utils/jaxsim_dataclass.py,sha256=T8nZolb563mYJD7YvTmYW-z-hpkEiaK3cDbYHqwtqRc,11347
59
59
  jaxsim/utils/tracing.py,sha256=KDMoyVPlu2NJvFkhtZwq5AkqMMgajt3munvJom-vEjQ,650
60
- jaxsim-0.2.dev394.dist-info/LICENSE,sha256=EsU2z6_sWW4Zduzq3goVWjZoCZVKQsM4H_y0o7oRA7Q,1547
61
- jaxsim-0.2.dev394.dist-info/METADATA,sha256=MAzjWBb9UwRC3HkwkBP6ivGKFF7qKmbUT0oGDyB0VJE,7630
62
- jaxsim-0.2.dev394.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
63
- jaxsim-0.2.dev394.dist-info/top_level.txt,sha256=LxGMA8FLtXjQ6oI7N5gd_R_oSUHxpXxUEOfT1xS_ni0,7
64
- jaxsim-0.2.dev394.dist-info/RECORD,,
60
+ jaxsim-0.2.dev423.dist-info/LICENSE,sha256=eaYdFmdeMbiIoIiPzEK0MjP1S9wtFXjXNR5er49uLR0,1546
61
+ jaxsim-0.2.dev423.dist-info/METADATA,sha256=BMFakjnVVXsnLtDGb4uoF9oGeaE5rnwthff_C3HykJc,7644
62
+ jaxsim-0.2.dev423.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
63
+ jaxsim-0.2.dev423.dist-info/top_level.txt,sha256=LxGMA8FLtXjQ6oI7N5gd_R_oSUHxpXxUEOfT1xS_ni0,7
64
+ jaxsim-0.2.dev423.dist-info/RECORD,,