mani-skill-nightly 2025.7.8.44__py3-none-any.whl → 2025.7.16.652__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.
- mani_skill/utils/geometry/rotation_conversions.py +5 -2
- mani_skill/utils/structs/articulation.py +46 -14
- mani_skill/utils/structs/articulation_joint.py +28 -12
- mani_skill/utils/structs/link.py +6 -12
- {mani_skill_nightly-2025.7.8.44.dist-info → mani_skill_nightly-2025.7.16.652.dist-info}/METADATA +1 -1
- {mani_skill_nightly-2025.7.8.44.dist-info → mani_skill_nightly-2025.7.16.652.dist-info}/RECORD +9 -9
- {mani_skill_nightly-2025.7.8.44.dist-info → mani_skill_nightly-2025.7.16.652.dist-info}/LICENSE +0 -0
- {mani_skill_nightly-2025.7.8.44.dist-info → mani_skill_nightly-2025.7.16.652.dist-info}/WHEEL +0 -0
- {mani_skill_nightly-2025.7.8.44.dist-info → mani_skill_nightly-2025.7.16.652.dist-info}/top_level.txt +0 -0
@@ -291,10 +291,13 @@ def matrix_to_euler_angles(matrix: torch.Tensor, convention: str) -> torch.Tenso
|
|
291
291
|
tait_bryan = i0 != i2
|
292
292
|
if tait_bryan:
|
293
293
|
central_angle = torch.asin(
|
294
|
-
matrix[..., i0, i2]
|
294
|
+
torch.clamp(matrix[..., i0, i2], -1.0 + 1e-8, 1.0 - 1e-8)
|
295
|
+
* (-1.0 if i0 - i2 in [-1, 2] else 1.0)
|
295
296
|
)
|
296
297
|
else:
|
297
|
-
central_angle = torch.acos(
|
298
|
+
central_angle = torch.acos(
|
299
|
+
torch.clamp(matrix[..., i0, i0], -1.0 + 1e-8, 1.0 - 1e-8)
|
300
|
+
)
|
298
301
|
|
299
302
|
o = (
|
300
303
|
_angle_from_tan(
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
3
3
|
from collections import defaultdict
|
4
4
|
from dataclasses import dataclass, field
|
5
5
|
from functools import cached_property
|
6
|
-
from typing import TYPE_CHECKING, Dict, List, Tuple, Union
|
6
|
+
from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Union
|
7
7
|
|
8
8
|
import numpy as np
|
9
9
|
import sapien
|
@@ -496,10 +496,30 @@ class Articulation(BaseStruct[physx.PhysxArticulation]):
|
|
496
496
|
"""
|
497
497
|
return self.get_net_contact_impulses(link_names) / self.scene.timestep
|
498
498
|
|
499
|
-
def get_joint_target_indices(
|
499
|
+
def get_joint_target_indices(
|
500
|
+
self, joint_indices: Union[Array, List[int], List[ArticulationJoint]]
|
501
|
+
):
|
502
|
+
"""
|
503
|
+
Gets the meshgrid indexes for indexing px.cuda_articulation_target_* values given a 1D list of joint indexes or a 1D list of ArticulationJoint objects.
|
504
|
+
|
505
|
+
Internally the given input is made to a tuple for a cache key and is used to cache results for fast lookup in the future, particularly for large-scale GPU simulations.
|
506
|
+
"""
|
507
|
+
if isinstance(joint_indices, list):
|
508
|
+
joint_indices = tuple(joint_indices)
|
500
509
|
if joint_indices not in self._cached_joint_target_indices:
|
510
|
+
vals = joint_indices
|
511
|
+
if isinstance(joint_indices[0], ArticulationJoint):
|
512
|
+
for joint in joint_indices:
|
513
|
+
assert (
|
514
|
+
joint.articulation == self
|
515
|
+
), "Can only fetch this articulation's joint_target_indices when provided joints from this articulation"
|
516
|
+
vals = [
|
517
|
+
x.active_index[0] for x in joint_indices
|
518
|
+
] # active_index on joint is batched but it should be the same value across all managed joint objects
|
501
519
|
self._cached_joint_target_indices[joint_indices] = torch.meshgrid(
|
502
|
-
self._data_index,
|
520
|
+
self._data_index,
|
521
|
+
common.to_tensor(vals, device=self.device),
|
522
|
+
indexing="ij",
|
503
523
|
)
|
504
524
|
return self._cached_joint_target_indices[joint_indices]
|
505
525
|
|
@@ -516,7 +536,7 @@ class Articulation(BaseStruct[physx.PhysxArticulation]):
|
|
516
536
|
of shape (N, M) where N is the number of environments and M is the number of active joints.
|
517
537
|
"""
|
518
538
|
if self.scene.gpu_sim_enabled:
|
519
|
-
return self.px.cuda_articulation_target_qpos[
|
539
|
+
return self.px.cuda_articulation_target_qpos.torch()[
|
520
540
|
self.get_joint_target_indices(self.active_joints)
|
521
541
|
]
|
522
542
|
else:
|
@@ -529,7 +549,7 @@ class Articulation(BaseStruct[physx.PhysxArticulation]):
|
|
529
549
|
of shape (N, M) where N is the number of environments and M is the number of active joints.
|
530
550
|
"""
|
531
551
|
if self.scene.gpu_sim_enabled:
|
532
|
-
return self.px.cuda_articulation_target_qvel[
|
552
|
+
return self.px.cuda_articulation_target_qvel.torch()[
|
533
553
|
self.get_joint_target_indices(self.active_joints)
|
534
554
|
]
|
535
555
|
else:
|
@@ -853,16 +873,23 @@ class Articulation(BaseStruct[physx.PhysxArticulation]):
|
|
853
873
|
def set_joint_drive_targets(
|
854
874
|
self,
|
855
875
|
targets: Array,
|
856
|
-
joints: List[ArticulationJoint] = None,
|
857
|
-
joint_indices: torch.Tensor = None,
|
876
|
+
joints: Optional[List[ArticulationJoint]] = None,
|
877
|
+
joint_indices: Optional[torch.Tensor] = None,
|
858
878
|
):
|
859
879
|
"""
|
860
|
-
Set drive targets on active joints
|
880
|
+
Set drive targets on active joints given joints. For GPU simulation only joint_indices argument is supported, which should be a 1D list of the active joint indices in the articulation.
|
881
|
+
|
882
|
+
joints argument will always be used when possible and is the recommended approach. On CPU simulation the joints argument is required, joint_indices is not supported.
|
861
883
|
"""
|
862
884
|
if self.scene.gpu_sim_enabled:
|
863
885
|
targets = common.to_tensor(targets, device=self.device)
|
864
|
-
|
865
|
-
|
886
|
+
if joints is not None:
|
887
|
+
gx, gy = self.get_joint_target_indices(joints)
|
888
|
+
else:
|
889
|
+
gx, gy = self.get_joint_target_indices(joint_indices)
|
890
|
+
self.px.cuda_articulation_target_qpos.torch()[
|
891
|
+
gx[self.scene._reset_mask], gy[self.scene._reset_mask]
|
892
|
+
] = targets
|
866
893
|
else:
|
867
894
|
for i, joint in enumerate(joints):
|
868
895
|
joint.set_drive_target(targets[0, i])
|
@@ -870,15 +897,20 @@ class Articulation(BaseStruct[physx.PhysxArticulation]):
|
|
870
897
|
def set_joint_drive_velocity_targets(
|
871
898
|
self,
|
872
899
|
targets: Array,
|
873
|
-
joints: List[ArticulationJoint] = None,
|
874
|
-
joint_indices: torch.Tensor = None,
|
900
|
+
joints: Optional[List[ArticulationJoint]] = None,
|
901
|
+
joint_indices: Optional[torch.Tensor] = None,
|
875
902
|
):
|
876
903
|
"""
|
877
|
-
Set drive velocity targets on active joints
|
904
|
+
Set drive velocity targets on active joints given joints. For GPU simulation only joint_indices argument is supported, which should be a 1D list of the active joint indices in the articulation.
|
905
|
+
|
906
|
+
joints argument will always be used when possible and is the recommended approach. On CPU simulation the joints argument is required, joint_indices is not supported.
|
878
907
|
"""
|
879
908
|
if self.scene.gpu_sim_enabled:
|
880
909
|
targets = common.to_tensor(targets, device=self.device)
|
881
|
-
|
910
|
+
if joints is not None:
|
911
|
+
gx, gy = self.get_joint_target_indices(joints)
|
912
|
+
else:
|
913
|
+
gx, gy = self.get_joint_target_indices(joint_indices)
|
882
914
|
self.px.cuda_articulation_target_qvel.torch()[gx, gy] = targets
|
883
915
|
else:
|
884
916
|
for i, joint in enumerate(joints):
|
@@ -240,20 +240,28 @@ class ArticulationJoint(BaseStruct[physx.PhysxArticulationJoint]):
|
|
240
240
|
|
241
241
|
@property
|
242
242
|
def drive_target(self) -> torch.Tensor:
|
243
|
+
assert (
|
244
|
+
self.active_index is not None
|
245
|
+
), "Cannot get drive position targets of inactive joints"
|
243
246
|
if self.scene.gpu_sim_enabled:
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
+
return self.articulation.px.cuda_articulation_target_qpos.torch()[
|
248
|
+
self._data_index,
|
249
|
+
self.active_index,
|
250
|
+
]
|
247
251
|
else:
|
248
252
|
return torch.from_numpy(self._objs[0].drive_target[None, :])
|
249
253
|
|
250
254
|
@drive_target.setter
|
251
255
|
def drive_target(self, arg1: Array) -> None:
|
252
256
|
arg1 = common.to_tensor(arg1, device=self.device)
|
257
|
+
assert (
|
258
|
+
self.active_index is not None
|
259
|
+
), "Cannot set drive position targets of inactive joints"
|
253
260
|
if self.scene.gpu_sim_enabled:
|
254
|
-
|
255
|
-
|
256
|
-
|
261
|
+
self.articulation.px.cuda_articulation_target_qpos.torch()[
|
262
|
+
self._data_index[self.scene._reset_mask[self._scene_idxs]],
|
263
|
+
self.active_index,
|
264
|
+
] = arg1
|
257
265
|
else:
|
258
266
|
if arg1.shape == ():
|
259
267
|
arg1 = arg1.reshape(
|
@@ -263,20 +271,28 @@ class ArticulationJoint(BaseStruct[physx.PhysxArticulationJoint]):
|
|
263
271
|
|
264
272
|
@property
|
265
273
|
def drive_velocity_target(self) -> torch.Tensor:
|
274
|
+
assert (
|
275
|
+
self.active_index is not None
|
276
|
+
), "Cannot get drive velocity targets of inactive joints"
|
266
277
|
if self.scene.gpu_sim_enabled:
|
267
|
-
|
268
|
-
|
269
|
-
|
278
|
+
return self.articulation.px.cuda_articulation_target_qvel.torch()[
|
279
|
+
self._data_index,
|
280
|
+
self.active_index,
|
281
|
+
]
|
270
282
|
else:
|
271
283
|
return torch.from_numpy(self._objs[0].drive_velocity_target[None, :])
|
272
284
|
|
273
285
|
@drive_velocity_target.setter
|
274
286
|
def drive_velocity_target(self, arg1: Array) -> None:
|
275
287
|
arg1 = common.to_tensor(arg1, device=self.device)
|
288
|
+
assert (
|
289
|
+
self.active_index is not None
|
290
|
+
), "Cannot set drive velocity targets of inactive joints"
|
276
291
|
if self.scene.gpu_sim_enabled:
|
277
|
-
|
278
|
-
|
279
|
-
|
292
|
+
self.articulation.px.cuda_articulation_target_qvel.torch()[
|
293
|
+
self._data_index[self.scene._reset_mask[self._scene_idxs]],
|
294
|
+
self.active_index,
|
295
|
+
] = arg1
|
280
296
|
else:
|
281
297
|
if arg1.shape == ():
|
282
298
|
arg1 = arg1.reshape(
|
mani_skill/utils/structs/link.py
CHANGED
@@ -81,30 +81,23 @@ class Link(PhysxRigidBodyComponentStruct[physx.PhysxArticulationLinkComponent]):
|
|
81
81
|
merged_joint_indexes = []
|
82
82
|
merged_active_joint_indexes = []
|
83
83
|
articulation_objs = []
|
84
|
-
|
84
|
+
has_one_root_link = any(link.is_root.any() for link in links)
|
85
85
|
merged_scene_idxs = []
|
86
|
-
num_objs_per_actor = links[0]._num_objs
|
87
86
|
for link in links:
|
88
87
|
objs += link._objs
|
89
|
-
assert (
|
90
|
-
link.is_root == is_root
|
91
|
-
), "all links given to merge must all be root or all not be root links"
|
92
88
|
merged_scene_idxs.append(link._scene_idxs)
|
93
|
-
# if
|
94
|
-
if not
|
89
|
+
# if all links are not root links, then there are joints we can merge automatically
|
90
|
+
if not has_one_root_link:
|
95
91
|
joint_objs += link.joint._objs
|
96
92
|
articulation_objs += link.articulation._objs
|
97
93
|
|
98
94
|
merged_active_joint_indexes.append(link.joint.active_index)
|
99
95
|
merged_joint_indexes.append(link.joint.index)
|
100
|
-
assert (
|
101
|
-
link._num_objs == num_objs_per_actor
|
102
|
-
), "Each given link must have the same number of managed objects"
|
103
96
|
merged_scene_idxs = torch.concat(merged_scene_idxs)
|
104
97
|
merged_link = Link.create(
|
105
98
|
objs, scene=links[0].scene, scene_idxs=merged_scene_idxs
|
106
99
|
)
|
107
|
-
if not
|
100
|
+
if not has_one_root_link:
|
108
101
|
merged_active_joint_indexes = torch.concat(merged_active_joint_indexes)
|
109
102
|
merged_joint_indexes = torch.concat(merged_joint_indexes)
|
110
103
|
merged_joint = ArticulationJoint.create(
|
@@ -116,9 +109,10 @@ class Link(PhysxRigidBodyComponentStruct[physx.PhysxArticulationLinkComponent]):
|
|
116
109
|
active_joint_index=merged_active_joint_indexes,
|
117
110
|
)
|
118
111
|
merged_link.joint = merged_joint
|
112
|
+
if name is not None:
|
113
|
+
merged_joint.name = f"{name}_joints"
|
119
114
|
merged_joint.child_link = merged_link
|
120
115
|
# remove articulation reference as it does not make sense and is only used to instantiate some properties like the physx system
|
121
|
-
# TODO (stao): akin to the joint merging above, we can also make a view of the articulations of each link. Is it necessary?
|
122
116
|
merged_link.articulation = None
|
123
117
|
merged_link.name = name
|
124
118
|
merged_link.merged = True
|
{mani_skill_nightly-2025.7.8.44.dist-info → mani_skill_nightly-2025.7.16.652.dist-info}/RECORD
RENAMED
@@ -743,7 +743,7 @@ mani_skill/utils/building/assets/grid_texture_thin.png,sha256=f9L0Avi7C_kF3WvLcw
|
|
743
743
|
mani_skill/utils/geometry/__init__.py,sha256=0xcx-AqaRks_a2D-klRPfvV9CjSri_uI1ZqvbTc3Kgo,24
|
744
744
|
mani_skill/utils/geometry/bounding_cylinder.py,sha256=XO2vNVPl_JSceqpMPj0hH5L1SlVQFUZFQrRDy9rMOkI,4761
|
745
745
|
mani_skill/utils/geometry/geometry.py,sha256=6hvxNDVLNBV5yBzHxam7hjEI2PVGvp67gFr-7QN4JXM,6419
|
746
|
-
mani_skill/utils/geometry/rotation_conversions.py,sha256=
|
746
|
+
mani_skill/utils/geometry/rotation_conversions.py,sha256=GmivoJ3pmXCVRDPvZRxel-RP1G_rsLLRbFYa2VTHfu8,20673
|
747
747
|
mani_skill/utils/geometry/trimesh_utils.py,sha256=JruFftu0YPMut4Ig3ucv7lq_29dhKf1FH8Brc2nYY08,4558
|
748
748
|
mani_skill/utils/scene_builder/__init__.py,sha256=9jJXXQYBuYPabZ_GTIskD41_JX33R5ZT8jiaQOEEf0c,40
|
749
749
|
mani_skill/utils/scene_builder/registration.py,sha256=jz0CODY0myH0t1PHKwUuuGoed9dngq0l_8QPcs5Mp1Q,1508
|
@@ -801,12 +801,12 @@ mani_skill/utils/scene_builder/table/assets/table.glb,sha256=yw69itZDjBFg8JXZAr9
|
|
801
801
|
mani_skill/utils/structs/README.md,sha256=qnYKimp_ZkgNcduURrYQxVTimNmq_usDMKoQ8VtMdCs,286
|
802
802
|
mani_skill/utils/structs/__init__.py,sha256=BItR3Xe0z6xCrMHAEaH0AAAVyeonsQ3q-DJUyRUibAA,524
|
803
803
|
mani_skill/utils/structs/actor.py,sha256=L0p6vkr8rGtJmF22xAq8Q7nhXKnDD5dahzODSAko0bg,17394
|
804
|
-
mani_skill/utils/structs/articulation.py,sha256=
|
805
|
-
mani_skill/utils/structs/articulation_joint.py,sha256=
|
804
|
+
mani_skill/utils/structs/articulation.py,sha256=DfNu3irWZ7LWoMCQAR4t0F8QRnojYhmPBnk2LNYoTtw,38341
|
805
|
+
mani_skill/utils/structs/articulation_joint.py,sha256=xDQkCAXM3XZ56YgFqLwH5Ec8aFqhR5BqMSvDYCS0bzw,12972
|
806
806
|
mani_skill/utils/structs/base.py,sha256=meGQK5Y4KtHKLnp9VeOZS2gtwg9tE55whuEeqOguBaI,19465
|
807
807
|
mani_skill/utils/structs/decorators.py,sha256=Lv6wQ989dOnreo2tB-qopDnkeBp_jsn1pmfUR-OY8VQ,535
|
808
808
|
mani_skill/utils/structs/drive.py,sha256=UPQDkGbXS-CMRsZ1MHCb9s1vfAo5nqsywF83wKBVzSY,7505
|
809
|
-
mani_skill/utils/structs/link.py,sha256=
|
809
|
+
mani_skill/utils/structs/link.py,sha256=Syq2_PSwmQGj1KOkmRjmDETIus_SR6qXorc2mnsDq38,13792
|
810
810
|
mani_skill/utils/structs/pose.py,sha256=76Sjrs-y3f8YhnuqMZNih-NxcnhnfomIbnNW1SWqK6A,11938
|
811
811
|
mani_skill/utils/structs/render_camera.py,sha256=cNdi_DMsrHDqO-vHjwEIMVFxVvPHNTmVZe0sCQ1XMbI,12599
|
812
812
|
mani_skill/utils/structs/types.py,sha256=eDezQSxtu8IyjIe4k6m8amQn7eYIuP9iLatXbr7FYH8,3810
|
@@ -827,8 +827,8 @@ mani_skill/vector/wrappers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
|
|
827
827
|
mani_skill/vector/wrappers/gymnasium.py,sha256=aNPB-2oGDLep8qzdsuTSIlwGGO0OGQAQ193LefOGoTk,7434
|
828
828
|
mani_skill/vector/wrappers/sb3.py,sha256=SlXdiEPqcNHYMhJCzA29kBU6zK7DKTe1nc0L6Z3QQtY,4722
|
829
829
|
mani_skill/viewer/__init__.py,sha256=srvDBsk4LQU75K2VIttrhiQ68p_ro7PSDqQRls2PY5c,1722
|
830
|
-
mani_skill_nightly-2025.7.
|
831
|
-
mani_skill_nightly-2025.7.
|
832
|
-
mani_skill_nightly-2025.7.
|
833
|
-
mani_skill_nightly-2025.7.
|
834
|
-
mani_skill_nightly-2025.7.
|
830
|
+
mani_skill_nightly-2025.7.16.652.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
831
|
+
mani_skill_nightly-2025.7.16.652.dist-info/METADATA,sha256=nQX9LU5x3aBDXUSvbsL8fYUz68hbRwcppNKGRoi3odU,9271
|
832
|
+
mani_skill_nightly-2025.7.16.652.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
833
|
+
mani_skill_nightly-2025.7.16.652.dist-info/top_level.txt,sha256=bkBgOVl_MZMoQx2aRFsSFEYlZLxjWlip5vtJ39FB3jA,11
|
834
|
+
mani_skill_nightly-2025.7.16.652.dist-info/RECORD,,
|
{mani_skill_nightly-2025.7.8.44.dist-info → mani_skill_nightly-2025.7.16.652.dist-info}/LICENSE
RENAMED
File without changes
|
{mani_skill_nightly-2025.7.8.44.dist-info → mani_skill_nightly-2025.7.16.652.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|