mani-skill-nightly 2025.8.19.1758__py3-none-any.whl → 2025.8.19.2202__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.

Potentially problematic release.


This version of mani-skill-nightly might be problematic. Click here for more details.

@@ -1,4 +1,4 @@
1
- from dataclasses import dataclass
1
+ from dataclasses import dataclass, field
2
2
  from typing import Literal, Optional, Sequence, Union
3
3
 
4
4
  import numpy as np
@@ -9,9 +9,11 @@ from mani_skill.agents.controllers.utils.kinematics import Kinematics
9
9
  from mani_skill.utils import gym_utils, sapien_utils
10
10
  from mani_skill.utils.geometry.rotation_conversions import (
11
11
  euler_angles_to_matrix,
12
+ matrix_to_euler_angles,
12
13
  matrix_to_quaternion,
13
14
  quaternion_apply,
14
15
  quaternion_multiply,
16
+ quaternion_to_matrix,
15
17
  )
16
18
  from mani_skill.utils.structs import Pose
17
19
  from mani_skill.utils.structs.types import Array, DriveMode
@@ -72,13 +74,14 @@ class PDEEPosController(PDJointPosController):
72
74
 
73
75
  def reset(self):
74
76
  super().reset()
75
- if self._target_pose is None:
76
- self._target_pose = self.ee_pose_at_base
77
- else:
78
- # TODO (stao): this is a strange way to mask setting individual batched pose parts
79
- self._target_pose.raw_pose[self.scene._reset_mask] = (
80
- self.ee_pose_at_base.raw_pose[self.scene._reset_mask]
81
- )
77
+ if self.config.use_target:
78
+ if self._target_pose is None:
79
+ self._target_pose = self.ee_pose_at_base
80
+ else:
81
+ # TODO (stao): this is a strange way to mask setting individual batched pose parts
82
+ self._target_pose.raw_pose[
83
+ self.scene._reset_mask
84
+ ] = self.ee_pose_at_base.raw_pose[self.scene._reset_mask]
82
85
 
83
86
  def compute_target_pose(self, prev_ee_pose_at_base, action):
84
87
  # Keep the current rotation and change the position
@@ -105,14 +108,22 @@ class PDEEPosController(PDJointPosController):
105
108
  else:
106
109
  prev_ee_pose_at_base = self.ee_pose_at_base
107
110
 
108
- self._target_pose = self.compute_target_pose(prev_ee_pose_at_base, action)
111
+ # we only need to use the target pose for CPU sim or if a virtual target is enabled
112
+ # if we have no virtual target and using the gpu sim we can directly use the given action without
113
+ # having to recompute the new target pose based on the action delta.
114
+ ik_via_target_pose = self.config.use_target or not self.scene.gpu_sim_enabled
115
+ if ik_via_target_pose:
116
+ self._target_pose = self.compute_target_pose(prev_ee_pose_at_base, action)
109
117
  pos_only = type(self.config) == PDEEPosControllerConfig
118
+ if pos_only:
119
+ action = torch.hstack([action, torch.zeros(action.shape[0], 3, device=self.device)])
120
+
110
121
  self._target_qpos = self.kinematics.compute_ik(
111
- self._target_pose,
112
- self.articulation.get_qpos(),
113
- pos_only=pos_only,
114
- action=action,
115
- use_delta_ik_solver=self.config.use_delta and not self.config.use_target,
122
+ pose=self._target_pose if ik_via_target_pose else action,
123
+ q0=self.articulation.get_qpos(),
124
+ is_delta_pose=not ik_via_target_pose and self.config.use_delta,
125
+ current_pose=self.ee_pose_at_base,
126
+ solver_config=self.config.delta_solver_config,
116
127
  )
117
128
  if self._target_qpos is None:
118
129
  self._target_qpos = self._start_qpos
@@ -175,6 +186,10 @@ class PDEEPosControllerConfig(ControllerConfig):
175
186
  interpolate: bool = False
176
187
  normalize_action: bool = True
177
188
  """Whether to normalize each action dimension into a range of [-1, 1]. Normally for most machine learning workflows this is recommended to be kept true."""
189
+ delta_solver_config: dict = field(
190
+ default_factory=lambda: dict(type="levenberg_marquardt", alpha=1.0)
191
+ )
192
+ """Configuration for the delta IK solver. Default is `dict(type="levenberg_marquardt", alpha=1.0)`. type can be one of "levenberg_marquardt" or "pseudo_inverse". alpha is a scaling term applied to the delta joint positions generated by the solver. Generally levenberg_marquardt is faster and more accurate than pseudo_inverse and is the recommended option, see https://github.com/haosulab/ManiSkill/issues/955#issuecomment-2742253342 for some analysis on performance."""
178
193
  drive_mode: Union[Sequence[DriveMode], DriveMode] = "force"
179
194
  controller_cls = PDEEPosController
180
195
 
@@ -4,7 +4,9 @@ Code for kinematics utilities on CPU/GPU
4
4
 
5
5
  from contextlib import contextmanager, redirect_stderr, redirect_stdout
6
6
  from os import devnull
7
- from typing import List
7
+ from typing import List, Optional, Union
8
+
9
+ from mani_skill.utils.geometry import rotation_conversions
8
10
 
9
11
  try:
10
12
  import pytorch_kinematics as pk
@@ -182,62 +184,69 @@ class Kinematics:
182
184
 
183
185
  def compute_ik(
184
186
  self,
185
- target_pose: Pose,
187
+ pose: Union[Pose, torch.Tensor],
186
188
  q0: torch.Tensor,
187
- pos_only: bool = False,
188
- action=None,
189
- use_delta_ik_solver: bool = False,
189
+ is_delta_pose: bool = False,
190
+ current_pose: Optional[Pose] = None,
191
+ solver_config: dict = dict(type="levenberg_marquardt", solver_iterations=1, alpha=1.0),
190
192
  ):
191
- """Given a target pose, via inverse kinematics compute the target joint positions that will achieve the target pose
193
+ """Given a target pose, initial joint positions, this computes the target joint positions that will achieve the target pose.
194
+ For optimization you can also provide the delta pose instead and specify is_delta_pose=True.
192
195
 
193
196
  Args:
194
- target_pose (Pose): target pose of the end effector in the world frame. note this is not relative to the robot base frame!
195
- q0 (torch.Tensor): initial joint positions of every active joint in the articulation
196
- pos_only (bool): if True, only the position of the end link is considered in the IK computation
197
- action (torch.Tensor): delta action to be applied to the articulation. Used for fast delta IK solutions on the GPU.
198
- use_delta_ik_solver (bool): If true, returns the target joint positions that correspond with a delta IK solution. This is specifically
199
- used for GPU simulation to determine which GPU IK algorithm to use.
197
+ pose (Pose): target pose in the world frame. Note this is not relative to the robot base frame!
198
+ q0 (torch.Tensor): initial joint positions of each active joint in the articulation. Note that this function will mask out the joints that are not kinematically relevant.
199
+ is_delta_pose (bool): if True, the `pose` parameter should be a delta pose. It can also be a tensor of shape (N, 6) with the first 3 channels for translation and the last 3 channels for rotation in the euler angle format.
200
+ current_pose (Optional[Pose]): current pose of the controlled link in the world frame. This is used to optimize the function by avoiding computing the current pose from q0 to compute the delta pose. If is_delta_pose is False, this is not used.
201
+ solver_config (dict): configuration for the IK solver. Default is `dict(type="levenberg_marquardt", alpha=1.0)`. type can be one of "levenberg_marquardt" or "pseudo_inverse". alpha is a scaling term applied to the delta joint positions generated by the solver.
200
202
  """
203
+ assert isinstance(pose, Pose) or pose.shape[1] == 6, "pose must be a Pose or a tensor with shape (N, 6)"
201
204
  if self.use_gpu_ik:
205
+ B = pose.shape[0]
202
206
  q0 = q0[:, self.active_ancestor_joint_idxs]
203
- if not use_delta_ik_solver:
204
- tf = pk.Transform3d(
205
- pos=target_pose.p,
206
- rot=target_pose.q,
207
- device=self.device,
208
- )
209
- self.pik.initial_config = q0 # shape (num_retries, active_ancestor_dof)
210
- result = self.pik.solve(
211
- tf
212
- ) # produce solutions in shape (B, num_retries/initial_configs, active_ancestor_dof)
213
- # TODO return mask for invalid solutions. CPU returns None at the moment
214
- return result.solutions[:, 0, :]
207
+ if not is_delta_pose:
208
+ if current_pose is None:
209
+ current_pose = self.pk_chain.forward_kinematics(q0).get_matrix()
210
+ current_pose = Pose.create_from_pq(current_pose[:, :3, 3], rotation_conversions.matrix_to_quaternion(current_pose[:, :3, :3]))
211
+ if isinstance(pose, torch.Tensor):
212
+ target_pos, target_rot = pose[:, 0:3], pose[:, 3:6]
213
+ target_quat = rotation_conversions.matrix_to_quaternion(
214
+ rotation_conversions.euler_angles_to_matrix(target_rot, "XYZ")
215
+ )
216
+ pose = Pose.create_from_pq(target_pos, target_quat)
217
+ if isinstance(pose, Pose):
218
+ # the following assumes root_translation:root_aligned_body_rotation control frame
219
+ translation = pose.p - current_pose.p
220
+ quaternion = rotation_conversions.quaternion_multiply(pose.q, rotation_conversions.quaternion_invert(current_pose.q))
221
+ pose = Pose.create_from_pq(translation, quaternion)
222
+ if isinstance(pose, Pose):
223
+ delta_pose = torch.zeros((B, 6), device=self.device, dtype=torch.float32)
224
+ delta_pose[:, 0:3] = pose.p
225
+ delta_pose[:, 3:6] = rotation_conversions.matrix_to_euler_angles(rotation_conversions.quaternion_to_matrix(pose.q), "XYZ")
215
226
  else:
216
- jacobian = self.pk_chain.jacobian(q0)
217
- # code commented out below is the fast kinematics method
218
- # jacobian = (
219
- # self.fast_kinematics_model.jacobian_mixed_frame_pytorch(
220
- # self.articulation.get_qpos()[:, self.active_ancestor_joint_idxs]
221
- # )
222
- # .view(-1, len(self.active_ancestor_joints), 6)
223
- # .permute(0, 2, 1)
224
- # )
225
- # jacobian = jacobian[:, :, self.qmask]
226
- if pos_only:
227
- jacobian = jacobian[:, 0:3]
228
-
229
- # NOTE (arth): use only the parts of the jacobian that correspond to the active joints
230
- jacobian = jacobian[:, :, self.qmask]
227
+ delta_pose = pose
228
+ jacobian = self.pk_chain.jacobian(q0)[:, :, self.qmask]
229
+ if solver_config["type"] == "levenberg_marquardt":
230
+ lambd = 0.0001 # Regularization parameter to ensure J^T * J is non-singular.
231
+ J_T = jacobian.transpose(1, 2)
232
+ lfs_A = torch.bmm(J_T, jacobian) + lambd * torch.eye(
233
+ len(self.qmask), device=self.device
234
+ )
235
+ rhs_B = torch.bmm(J_T, delta_pose.unsqueeze(-1))
236
+ delta_joint_pos = torch.linalg.solve(lfs_A, rhs_B)
231
237
 
238
+ elif solver_config["type"] == "pseudo_inverse":
232
239
  # NOTE (stao): this method of IK is from https://mathweb.ucsd.edu/~sbuss/ResearchWeb/ikmethods/iksurvey.pdf by Samuel R. Buss
233
- delta_joint_pos = torch.linalg.pinv(jacobian) @ action.unsqueeze(-1)
240
+ delta_joint_pos = torch.linalg.pinv(jacobian) @ delta_pose.unsqueeze(-1)
234
241
 
235
- return q0[:, self.qmask] + delta_joint_pos.squeeze(-1)
242
+ return q0[:, self.qmask] + solver_config[
243
+ "alpha"
244
+ ] * delta_joint_pos.squeeze(-1)
236
245
  else:
237
246
  q0 = q0[:, self.pmodel_active_joint_indices]
238
247
  result, success, error = self.pmodel.compute_inverse_kinematics(
239
248
  self.end_link_idx,
240
- target_pose.sp,
249
+ pose.sp,
241
250
  initial_qpos=q0.cpu().numpy()[0],
242
251
  active_qmask=self.qmask,
243
252
  max_iterations=100,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mani-skill-nightly
3
- Version: 2025.8.19.1758
3
+ Version: 2025.8.19.2202
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
@@ -9,12 +9,12 @@ mani_skill/agents/controllers/__init__.py,sha256=tsd27dW6brQBm563CddUGtFMBNAxe_M
9
9
  mani_skill/agents/controllers/base_controller.py,sha256=JcKdQF7VN5YWzFOPwdYKShptfHVnxts78L9yPh4-Kto,13337
10
10
  mani_skill/agents/controllers/passive_controller.py,sha256=1cZp758AVuABvgWOzCeguBbbB8wJ6hF_cqN-k_vx5Kw,1322
11
11
  mani_skill/agents/controllers/pd_base_vel.py,sha256=-3ZzLZ9nRDMGHWnFE7c4reEbC3jHtQJCOx3LmArz95g,2868
12
- mani_skill/agents/controllers/pd_ee_pose.py,sha256=iCqK8q1ds7VTH4tkQleyryiBTIts70yS4SEQ0jzpMYI,12134
12
+ mani_skill/agents/controllers/pd_ee_pose.py,sha256=alYkN02OVYDbj7i1OqC6hC87o_FZ85SxHXNmBFXR-lw,13447
13
13
  mani_skill/agents/controllers/pd_joint_pos.py,sha256=dSdOu1Q-sGyG3rJnWYNNmzXW8U6_zU3zcIY4wgHRvI8,11108
14
14
  mani_skill/agents/controllers/pd_joint_pos_vel.py,sha256=wgiXmenTVIao1Tm1vtdJWTZRFJMB_yQBNd5vQaP8WXw,2489
15
15
  mani_skill/agents/controllers/pd_joint_vel.py,sha256=VZF06ISCkdKBX_fUHxb7mdl9GN1Lob5dhrFGlwCx16Q,1957
16
16
  mani_skill/agents/controllers/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
- mani_skill/agents/controllers/utils/kinematics.py,sha256=FiSE1nfZejShEqvua9buzA_SCBuEP9OiAd7LpLbSp44,10415
17
+ mani_skill/agents/controllers/utils/kinematics.py,sha256=FxREZaBRjUfc7S-jf0cLhN3HivTPxhq3AnO5zHE2nyI,11920
18
18
  mani_skill/agents/robots/__init__.py,sha256=lvW8t2bn2UjuWZ7PsYiKqMnHaMLvGVw6itBhxwHaauk,737
19
19
  mani_skill/agents/robots/allegro_hand/__init__.py,sha256=PWH6MMv2i5g1xi76_E-YJLtKFLVKxkJgQ96GD_YeQN4,104
20
20
  mani_skill/agents/robots/allegro_hand/allegro.py,sha256=MnU04fCcvppTGJHdhgvs2OqUKToQtNMXbs2bFM5sXiU,4896
@@ -826,8 +826,8 @@ mani_skill/vector/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
826
826
  mani_skill/vector/wrappers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
827
827
  mani_skill/vector/wrappers/gymnasium.py,sha256=voHNmYg5Jyy-laMSC2Fd8VggQvhXw3NnfYLbD9QDXAc,7305
828
828
  mani_skill/vector/wrappers/sb3.py,sha256=SlXdiEPqcNHYMhJCzA29kBU6zK7DKTe1nc0L6Z3QQtY,4722
829
- mani_skill_nightly-2025.8.19.1758.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
830
- mani_skill_nightly-2025.8.19.1758.dist-info/METADATA,sha256=Ewkt0h5OQrqfFT7bTTCIMC-8adHb1eP5i0KF0giZxPU,9316
831
- mani_skill_nightly-2025.8.19.1758.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
832
- mani_skill_nightly-2025.8.19.1758.dist-info/top_level.txt,sha256=bkBgOVl_MZMoQx2aRFsSFEYlZLxjWlip5vtJ39FB3jA,11
833
- mani_skill_nightly-2025.8.19.1758.dist-info/RECORD,,
829
+ mani_skill_nightly-2025.8.19.2202.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
830
+ mani_skill_nightly-2025.8.19.2202.dist-info/METADATA,sha256=AUKAKHdJL1CFsXi4rUeZLyCvD966GO51Pu6e-fg-r70,9316
831
+ mani_skill_nightly-2025.8.19.2202.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
832
+ mani_skill_nightly-2025.8.19.2202.dist-info/top_level.txt,sha256=bkBgOVl_MZMoQx2aRFsSFEYlZLxjWlip5vtJ39FB3jA,11
833
+ mani_skill_nightly-2025.8.19.2202.dist-info/RECORD,,