mani-skill-nightly 2025.7.11.339__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.
@@ -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(self, joint_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, joint_indices, indexing="ij"
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,15 +873,20 @@ 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. Joint indices are required to be given for GPU sim, and joint objects are required for the CPU sim
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
- gx, gy = self.get_joint_target_indices(joint_indices)
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)
865
890
  self.px.cuda_articulation_target_qpos.torch()[
866
891
  gx[self.scene._reset_mask], gy[self.scene._reset_mask]
867
892
  ] = targets
@@ -872,15 +897,20 @@ class Articulation(BaseStruct[physx.PhysxArticulation]):
872
897
  def set_joint_drive_velocity_targets(
873
898
  self,
874
899
  targets: Array,
875
- joints: List[ArticulationJoint] = None,
876
- joint_indices: torch.Tensor = None,
900
+ joints: Optional[List[ArticulationJoint]] = None,
901
+ joint_indices: Optional[torch.Tensor] = None,
877
902
  ):
878
903
  """
879
- Set drive velocity targets on active joints. Joint indices are required to be given for GPU sim, and joint objects are required for the CPU sim
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.
880
907
  """
881
908
  if self.scene.gpu_sim_enabled:
882
909
  targets = common.to_tensor(targets, device=self.device)
883
- gx, gy = self.get_joint_target_indices(joint_indices)
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)
884
914
  self.px.cuda_articulation_target_qvel.torch()[gx, gy] = targets
885
915
  else:
886
916
  for i, joint in enumerate(joints):
@@ -240,18 +240,25 @@ 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
- raise NotImplementedError(
245
- "Getting drive targets of individual joints is not implemented yet."
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
- self.articulation.px.cuda_articulation_target_qpos[
261
+ self.articulation.px.cuda_articulation_target_qpos.torch()[
255
262
  self._data_index[self.scene._reset_mask[self._scene_idxs]],
256
263
  self.active_index,
257
264
  ] = arg1
@@ -264,20 +271,28 @@ class ArticulationJoint(BaseStruct[physx.PhysxArticulationJoint]):
264
271
 
265
272
  @property
266
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"
267
277
  if self.scene.gpu_sim_enabled:
268
- raise NotImplementedError(
269
- "Cannot read drive velocity targets at the moment in GPU simulation"
270
- )
278
+ return self.articulation.px.cuda_articulation_target_qvel.torch()[
279
+ self._data_index,
280
+ self.active_index,
281
+ ]
271
282
  else:
272
283
  return torch.from_numpy(self._objs[0].drive_velocity_target[None, :])
273
284
 
274
285
  @drive_velocity_target.setter
275
286
  def drive_velocity_target(self, arg1: Array) -> None:
276
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"
277
291
  if self.scene.gpu_sim_enabled:
278
- raise NotImplementedError(
279
- "Cannot set drive velocity targets at the moment in GPU simulation"
280
- )
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
281
296
  else:
282
297
  if arg1.shape == ():
283
298
  arg1 = arg1.reshape(
@@ -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
- is_root = links[0].is_root
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 link is not root, then there are joints we can merge automatically
94
- if not is_root:
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 is_root:
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mani-skill-nightly
3
- Version: 2025.7.11.339
3
+ Version: 2025.7.16.652
4
4
  Summary: ManiSkill3: A Unified Benchmark for Generalizable Manipulation Skills
5
5
  Home-page: https://github.com/haosulab/ManiSkill
6
6
  Author: ManiSkill contributors
@@ -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=4GKzXWG4y21jSyMIkdlYgRuHENXyimXu2M-_u51JxoA,36454
805
- mani_skill/utils/structs/articulation_joint.py,sha256=gF39AvjbsMOLaFP2gkU_rhRW3G9HWXG6jevHzkIU2oo,12349
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=XOB3b9RSN-XV11Jwlam3e6ca1fJ1cfKdZKg_lLIn1tw,14116
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.11.339.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
831
- mani_skill_nightly-2025.7.11.339.dist-info/METADATA,sha256=BPCd5GWbITO87BSSOX2IQWTKf6W-xCluLEdJi73F2DA,9271
832
- mani_skill_nightly-2025.7.11.339.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
833
- mani_skill_nightly-2025.7.11.339.dist-info/top_level.txt,sha256=bkBgOVl_MZMoQx2aRFsSFEYlZLxjWlip5vtJ39FB3jA,11
834
- mani_skill_nightly-2025.7.11.339.dist-info/RECORD,,
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,,