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.
- mani_skill/agents/controllers/pd_ee_pose.py +29 -14
- mani_skill/agents/controllers/utils/kinematics.py +51 -42
- {mani_skill_nightly-2025.8.19.1758.dist-info → mani_skill_nightly-2025.8.19.2202.dist-info}/METADATA +1 -1
- {mani_skill_nightly-2025.8.19.1758.dist-info → mani_skill_nightly-2025.8.19.2202.dist-info}/RECORD +7 -7
- {mani_skill_nightly-2025.8.19.1758.dist-info → mani_skill_nightly-2025.8.19.2202.dist-info}/LICENSE +0 -0
- {mani_skill_nightly-2025.8.19.1758.dist-info → mani_skill_nightly-2025.8.19.2202.dist-info}/WHEEL +0 -0
- {mani_skill_nightly-2025.8.19.1758.dist-info → mani_skill_nightly-2025.8.19.2202.dist-info}/top_level.txt +0 -0
|
@@ -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.
|
|
76
|
-
self._target_pose
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
self.
|
|
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
|
-
|
|
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
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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
|
-
|
|
187
|
+
pose: Union[Pose, torch.Tensor],
|
|
186
188
|
q0: torch.Tensor,
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
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,
|
|
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
|
-
|
|
195
|
-
q0 (torch.Tensor): initial joint positions of
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
#
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
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) @
|
|
240
|
+
delta_joint_pos = torch.linalg.pinv(jacobian) @ delta_pose.unsqueeze(-1)
|
|
234
241
|
|
|
235
|
-
|
|
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
|
-
|
|
249
|
+
pose.sp,
|
|
241
250
|
initial_qpos=q0.cpu().numpy()[0],
|
|
242
251
|
active_qmask=self.qmask,
|
|
243
252
|
max_iterations=100,
|
{mani_skill_nightly-2025.8.19.1758.dist-info → mani_skill_nightly-2025.8.19.2202.dist-info}/RECORD
RENAMED
|
@@ -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=
|
|
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=
|
|
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.
|
|
830
|
-
mani_skill_nightly-2025.8.19.
|
|
831
|
-
mani_skill_nightly-2025.8.19.
|
|
832
|
-
mani_skill_nightly-2025.8.19.
|
|
833
|
-
mani_skill_nightly-2025.8.19.
|
|
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,,
|
{mani_skill_nightly-2025.8.19.1758.dist-info → mani_skill_nightly-2025.8.19.2202.dist-info}/LICENSE
RENAMED
|
File without changes
|
{mani_skill_nightly-2025.8.19.1758.dist-info → mani_skill_nightly-2025.8.19.2202.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|