mani-skill-nightly 2025.4.3.2254__py3-none-any.whl → 2025.4.4.36__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.
Files changed (29) hide show
  1. mani_skill/agents/controllers/base_controller.py +2 -0
  2. mani_skill/agents/controllers/pd_joint_pos.py +113 -5
  3. mani_skill/agents/robots/__init__.py +2 -1
  4. mani_skill/agents/robots/floating_inspire_hand/__init__.py +1 -0
  5. mani_skill/agents/robots/floating_inspire_hand/floating_inspire_hand.py +176 -0
  6. mani_skill/agents/robots/panda/panda.py +1 -0
  7. mani_skill/assets/robots/inspire_hand/meshes/end_effector/inspire_hand/visual/L_hand_base_link.glb +0 -0
  8. mani_skill/assets/robots/inspire_hand/meshes/end_effector/inspire_hand/visual/L_thumb_metacarpal_base.glb +0 -0
  9. mani_skill/assets/robots/inspire_hand/meshes/end_effector/inspire_hand/visual/L_wrist_link.glb +0 -0
  10. mani_skill/assets/robots/inspire_hand/meshes/end_effector/inspire_hand/visual/R_hand_base_link.glb +0 -0
  11. mani_skill/assets/robots/inspire_hand/meshes/end_effector/inspire_hand/visual/R_thumb_metacarpal_base.glb +0 -0
  12. mani_skill/assets/robots/inspire_hand/meshes/end_effector/inspire_hand/visual/R_wrist_link.glb +0 -0
  13. mani_skill/assets/robots/inspire_hand/meshes/end_effector/inspire_hand/visual/index_ring_middle.glb +0 -0
  14. mani_skill/assets/robots/inspire_hand/meshes/end_effector/inspire_hand/visual/index_ring_proximal.glb +0 -0
  15. mani_skill/assets/robots/inspire_hand/meshes/end_effector/inspire_hand/visual/middle_middle.glb +0 -0
  16. mani_skill/assets/robots/inspire_hand/meshes/end_effector/inspire_hand/visual/middle_pinky_proximal.glb +0 -0
  17. mani_skill/assets/robots/inspire_hand/meshes/end_effector/inspire_hand/visual/pinky_middle.glb +0 -0
  18. mani_skill/assets/robots/inspire_hand/meshes/end_effector/inspire_hand/visual/thumb_distal.glb +0 -0
  19. mani_skill/assets/robots/inspire_hand/meshes/end_effector/inspire_hand/visual/thumb_metacarpal.glb +0 -0
  20. mani_skill/assets/robots/inspire_hand/meshes/end_effector/inspire_hand/visual/thumb_proximal.glb +0 -0
  21. mani_skill/assets/robots/inspire_hand/meshes/end_effector/inspire_hand/visual/wrist_base_link.glb +0 -0
  22. mani_skill/assets/robots/inspire_hand/urdf/end_effector/inspire_hand/inspire_hand_left.urdf +443 -0
  23. mani_skill/assets/robots/inspire_hand/urdf/end_effector/inspire_hand/inspire_hand_right.urdf +427 -0
  24. mani_skill/assets/robots/inspire_hand/urdf/end_effector/inspire_hand/inspire_hand_right_floating.urdf +505 -0
  25. {mani_skill_nightly-2025.4.3.2254.dist-info → mani_skill_nightly-2025.4.4.36.dist-info}/METADATA +1 -1
  26. {mani_skill_nightly-2025.4.3.2254.dist-info → mani_skill_nightly-2025.4.4.36.dist-info}/RECORD +29 -9
  27. {mani_skill_nightly-2025.4.3.2254.dist-info → mani_skill_nightly-2025.4.4.36.dist-info}/LICENSE +0 -0
  28. {mani_skill_nightly-2025.4.3.2254.dist-info → mani_skill_nightly-2025.4.4.36.dist-info}/WHEEL +0 -0
  29. {mani_skill_nightly-2025.4.3.2254.dist-info → mani_skill_nightly-2025.4.4.36.dist-info}/top_level.txt +0 -0
@@ -172,6 +172,8 @@ class BaseController:
172
172
  @dataclass
173
173
  class ControllerConfig:
174
174
  joint_names: List[str]
175
+ """the names of the joints to control. Note that some controller configurations might not actually let you directly control all the given joints
176
+ and will instead have some other implicit control (e.g. Passive controllers or mimic controllers)."""
175
177
  # NOTE(jigu): It is a class variable in this base class,
176
178
  # but you can inherit it and overwrite with an instance variable.
177
179
  controller_cls = BaseController
@@ -1,11 +1,12 @@
1
- from dataclasses import dataclass
2
- from typing import Sequence, Union
1
+ from dataclasses import dataclass, field
2
+ from typing import Dict, Sequence, Union
3
3
 
4
4
  import numpy as np
5
5
  import torch
6
6
  from gymnasium import spaces
7
7
 
8
8
  from mani_skill.utils import common
9
+ from mani_skill.utils.logging_utils import logger
9
10
  from mani_skill.utils.structs.types import Array, DriveMode
10
11
 
11
12
  from .base_controller import BaseController, ControllerConfig
@@ -124,12 +125,119 @@ class PDJointPosControllerConfig(ControllerConfig):
124
125
 
125
126
 
126
127
  class PDJointPosMimicController(PDJointPosController):
128
+ config: "PDJointPosMimicControllerConfig"
129
+
130
+ def _initialize_joints(self):
131
+ super()._initialize_joints()
132
+ # do some sanity checks and setup the mimic controller
133
+
134
+ self.mimic_joint_indices = []
135
+ self.mimic_control_joint_indices = []
136
+ if len(self.config.mimic) == 0:
137
+ if len(self.config.joint_names) == 2:
138
+ logger.warning(
139
+ f"Mimic targets dictionary is missing for controller config for {self.articulation.name}. Assuming the first joint is the control joint and the second joint is the mimic joint"
140
+ )
141
+ self.config.mimic = {
142
+ self.config.joint_names[0]: {"joint": self.config.joint_names[1]}
143
+ }
144
+ else:
145
+ raise ValueError(
146
+ "Mimic targets dictionary is missing. Please provide a mimic targets dictionary to setup mimic controllers withh more than 2 joints"
147
+ )
148
+
149
+ self._multiplier = torch.ones(
150
+ len(self.config.mimic), device=self.device
151
+ ) # this is parallel to self.mimic_joint_indices
152
+ self._offset = torch.zeros(len(self.config.mimic), device=self.device)
153
+
154
+ for i, (mimic_joint_name, mimic_data) in enumerate(self.config.mimic.items()):
155
+ control_joint_name = mimic_data["joint"]
156
+ multiplier = mimic_data.get("multiplier", 1.0)
157
+ offset = mimic_data.get("offset", 0.0)
158
+ assert (
159
+ self.articulation.joints_map[mimic_joint_name].active_index is not None
160
+ ), f"Mimic joint {mimic_joint_name} is not active, cannot be used as a mimic joint in a mimic controller"
161
+ assert (
162
+ self.articulation.joints_map[control_joint_name].active_index
163
+ is not None
164
+ ), f"Control joint {control_joint_name} is not active, cannot be used as a control joint in a mimic controller"
165
+
166
+ # NOTE (stao): we are assuming all the articulations are the exact same structure. At the moment I see very little reason to try and support training/evaluating on different embodiments
167
+ # simultaneously in one process
168
+ self.mimic_joint_indices.append(
169
+ torch.argwhere(
170
+ self.active_joint_indices
171
+ == self.articulation.joints_map[mimic_joint_name].active_index[0]
172
+ )
173
+ )
174
+ self.mimic_control_joint_indices.append(
175
+ torch.argwhere(
176
+ self.active_joint_indices
177
+ == self.articulation.joints_map[control_joint_name].active_index[0]
178
+ )
179
+ )
180
+
181
+ self._multiplier[i] = multiplier
182
+ self._offset[i] = offset
183
+
184
+ self.mimic_joint_indices = torch.tensor(
185
+ self.mimic_joint_indices, dtype=torch.int32, device=self.device
186
+ )
187
+ self.mimic_control_joint_indices = torch.tensor(
188
+ self.mimic_control_joint_indices, dtype=torch.int32, device=self.device
189
+ )
190
+ """list of control joint indices corresponding to mimic joint indices"""
191
+ self.control_joint_indices = torch.unique(self.mimic_control_joint_indices).to(
192
+ torch.int32
193
+ )
194
+ """list of all directly controlled joint indices"""
195
+
127
196
  def _get_joint_limits(self):
128
197
  joint_limits = super()._get_joint_limits()
129
- diff = joint_limits[0:-1] - joint_limits[1:]
130
- assert np.allclose(diff, 0), "Mimic joints should have the same limit"
131
- return joint_limits[0:1]
198
+ return joint_limits[self.control_joint_indices]
132
199
 
200
+ def set_action(self, action: Array):
201
+ action = self._preprocess_action(action)
202
+ self._step = 0
203
+ self._start_qpos = self.qpos
204
+ if self.config.use_delta:
205
+ if self.config.use_target:
206
+ self._target_qpos[:, self.control_joint_indices] += action
207
+ else:
208
+ self._target_qpos[:, self.control_joint_indices] = (
209
+ self._start_qpos[:, self.control_joint_indices] + action
210
+ )
211
+ else:
212
+ self._target_qpos[:, self.control_joint_indices] = action
213
+ self._target_qpos[:, self.mimic_joint_indices] = (
214
+ self._target_qpos[:, self.mimic_control_joint_indices]
215
+ * self._multiplier[None, :]
216
+ + self._offset[None, :]
217
+ )
218
+ if self.config.interpolate:
219
+ self._step_size = (self._target_qpos - self._start_qpos) / self._sim_steps
220
+ else:
221
+ self.set_drive_targets(self._target_qpos)
133
222
 
223
+
224
+ @dataclass
134
225
  class PDJointPosMimicControllerConfig(PDJointPosControllerConfig):
226
+ """
227
+ PD Joint Position mimic controller configuration. This kind of controller is used to emuluate a mimic joint. For some simulation backends mimic joints are not
228
+ well simulated and/or are hard to tune and so a mimic controller can be used for better stability as well as alignment with a real robot.
229
+
230
+ The `joint_names` field is expected to be a list of all the joints, whether they are the joints to be controlled or the joints that are controlled via mimicing.
231
+
232
+ `mimic` is a dictionary that maps the mimic joint name to a dictionary of the format dict(joint: str, multiplier: float, offset: float). `joint` is the controlling joint name and is required. All given joints in
233
+ `joint_names` must be in the `mimic` dictionary as either a key or a value. The ones that are keys are referred to as the mimic joints and the ones that are values
234
+ are referred to as the control joints. Mimic joints are the ones directly controlled by the agent/user and control joints are implicitly controlled by following the mimic joints via the following equation:
235
+
236
+ q_mimic = q_controlling * multiplier + offset
237
+
238
+ By default, the multiplier is 1.0 and the offset is 0.0.
239
+ """
240
+
135
241
  controller_cls = PDJointPosMimicController
242
+ mimic: Dict[str, Dict[str, float]] = field(default_factory=dict)
243
+ """the mimic targets. Maps the actual mimic joint name to a dictionary of the format dict(joint: str, multiplier: float, offset: float)"""
@@ -2,6 +2,7 @@ from .allegro_hand import *
2
2
  from .anymal import ANYmalC
3
3
  from .dclaw import DClaw
4
4
  from .fetch import Fetch
5
+ from .floating_inspire_hand import FloatingInspireHandRight
5
6
  from .floating_panda_gripper import FloatingPandaGripper
6
7
  from .floating_robotiq_2f_85_gripper import *
7
8
  from .googlerobot import *
@@ -14,6 +15,6 @@ from .unitree_go import *
14
15
  from .unitree_h1 import *
15
16
  from .ur_e import UR10e
16
17
  from .widowx import *
17
- from .xarm6 import *
18
18
  from .xarm import XArm7Ability
19
+ from .xarm6 import *
19
20
  from .xmate3 import Xmate3Robotiq
@@ -0,0 +1 @@
1
+ from .floating_inspire_hand import FloatingInspireHandRight
@@ -0,0 +1,176 @@
1
+ from copy import deepcopy
2
+
3
+ from mani_skill import PACKAGE_ASSET_DIR
4
+ from mani_skill.agents.base_agent import BaseAgent
5
+ from mani_skill.agents.controllers import *
6
+ from mani_skill.agents.registration import register_agent
7
+
8
+
9
+ @register_agent()
10
+ class FloatingInspireHandRight(BaseAgent):
11
+ uid = "floating_inspire_hand_right"
12
+ urdf_path = f"{PACKAGE_ASSET_DIR}/robots/inspire_hand/urdf/end_effector/inspire_hand/inspire_hand_right_floating.urdf"
13
+ urdf_config = dict(
14
+ _materials=dict(
15
+ finger=dict(static_friction=2.0, dynamic_friction=2.0, restitution=0.0)
16
+ ),
17
+ link=dict(
18
+ right_hand_hand_base_link=dict(
19
+ material="finger", patch_radius=0.1, min_patch_radius=0.1
20
+ ),
21
+ right_hand_thumb_distal=dict(
22
+ material="finger", patch_radius=0.1, min_patch_radius=0.1
23
+ ),
24
+ right_hand_thumb_metacarpal=dict(
25
+ material="finger", patch_radius=0.1, min_patch_radius=0.1
26
+ ),
27
+ right_hand_thumb_proximal=dict(
28
+ material="finger", patch_radius=0.1, min_patch_radius=0.1
29
+ ),
30
+ right_hand_index_proximal=dict(
31
+ material="finger", patch_radius=0.1, min_patch_radius=0.1
32
+ ),
33
+ right_hand_index_middle=dict(
34
+ material="finger", patch_radius=0.1, min_patch_radius=0.1
35
+ ),
36
+ right_hand_middle_proximal=dict(
37
+ material="finger", patch_radius=0.1, min_patch_radius=0.1
38
+ ),
39
+ right_hand_middle_middle=dict(
40
+ material="finger", patch_radius=0.1, min_patch_radius=0.1
41
+ ),
42
+ right_hand_ring_proximal=dict(
43
+ material="finger", patch_radius=0.1, min_patch_radius=0.1
44
+ ),
45
+ right_hand_ring_middle=dict(
46
+ material="finger", patch_radius=0.1, min_patch_radius=0.1
47
+ ),
48
+ right_hand_pinky_proximal=dict(
49
+ material="finger", patch_radius=0.1, min_patch_radius=0.1
50
+ ),
51
+ right_hand_pinky_middle=dict(
52
+ material="finger", patch_radius=0.1, min_patch_radius=0.1
53
+ ),
54
+ ),
55
+ )
56
+ disable_self_collisions = True
57
+ # you could model all of the fingers and disable certain impossible self collisions that occur
58
+ # but it is simpler and faster to just disable all self collisions. It is highly unlikely the hand self-collides to begin with.
59
+
60
+ root_joint_names = [
61
+ "root_x_axis_joint",
62
+ "root_y_axis_joint",
63
+ "root_z_axis_joint",
64
+ "root_x_rot_joint",
65
+ "root_y_rot_joint",
66
+ "root_z_rot_joint",
67
+ ]
68
+
69
+ @property
70
+ def _controller_configs(self):
71
+ float_pd_joint_pos = PDJointPosControllerConfig(
72
+ joint_names=self.root_joint_names,
73
+ lower=None,
74
+ upper=None,
75
+ stiffness=1e3,
76
+ damping=1e2,
77
+ force_limit=100,
78
+ normalize_action=False,
79
+ )
80
+ hand_joint_pos = PDJointPosControllerConfig(
81
+ joint_names=[
82
+ "right_hand_wrist_pitch_joint",
83
+ "right_hand_wrist_yaw_joint",
84
+ "right_hand_thumb_CMC_yaw_joint",
85
+ ],
86
+ lower=None,
87
+ upper=None,
88
+ stiffness=2e4,
89
+ damping=3e2,
90
+ force_limit=20,
91
+ normalize_action=False,
92
+ )
93
+ fingers_joint_pos = PDJointPosMimicControllerConfig(
94
+ joint_names=[
95
+ "right_hand_thumb_MCP_joint",
96
+ "right_hand_thumb_IP_joint",
97
+ "right_hand_index_PIP_joint",
98
+ "right_hand_middle_PIP_joint",
99
+ "right_hand_ring_PIP_joint",
100
+ "right_hand_pinky_PIP_joint",
101
+ "right_hand_thumb_CMC_pitch_joint",
102
+ "right_hand_index_MCP_joint",
103
+ "right_hand_middle_MCP_joint",
104
+ "right_hand_ring_MCP_joint",
105
+ "right_hand_pinky_MCP_joint",
106
+ ],
107
+ lower=None,
108
+ upper=None,
109
+ stiffness=2e4,
110
+ damping=3e2,
111
+ force_limit=20,
112
+ mimic={
113
+ "right_hand_thumb_MCP_joint": {
114
+ "joint": "right_hand_thumb_CMC_pitch_joint",
115
+ "multiplier": 1.3333333333333335,
116
+ "offset": -0.08144869842640205,
117
+ },
118
+ "right_hand_thumb_IP_joint": {
119
+ "joint": "right_hand_thumb_CMC_pitch_joint",
120
+ "multiplier": 0.6666666666666667,
121
+ "offset": -0.040724349213201026,
122
+ },
123
+ "right_hand_index_PIP_joint": {
124
+ "joint": "right_hand_index_MCP_joint",
125
+ "multiplier": 1.06399,
126
+ "offset": -0.16734800000000002,
127
+ },
128
+ "right_hand_middle_PIP_joint": {
129
+ "joint": "right_hand_middle_MCP_joint",
130
+ "multiplier": 1.06399,
131
+ "offset": -0.16734800000000002,
132
+ },
133
+ "right_hand_ring_PIP_joint": {
134
+ "joint": "right_hand_ring_MCP_joint",
135
+ "multiplier": 1.06399,
136
+ "offset": -0.16734800000000002,
137
+ },
138
+ "right_hand_pinky_PIP_joint": {
139
+ "joint": "right_hand_pinky_MCP_joint",
140
+ "multiplier": 1.06399,
141
+ "offset": -0.16734800000000002,
142
+ },
143
+ },
144
+ normalize_action=False,
145
+ )
146
+
147
+ hand_joint_delta_pos = deepcopy(hand_joint_pos)
148
+ hand_joint_delta_pos.use_delta = True
149
+ hand_joint_delta_pos.normalize_action = True
150
+ hand_joint_delta_pos.lower = -0.1
151
+ hand_joint_delta_pos.upper = 0.1
152
+
153
+ fingers_joint_delta_pos = deepcopy(fingers_joint_pos)
154
+ fingers_joint_delta_pos.use_delta = True
155
+ fingers_joint_delta_pos.normalize_action = True
156
+ fingers_joint_delta_pos.lower = -0.1
157
+ fingers_joint_delta_pos.upper = 0.1
158
+
159
+ float_pd_joint_delta_pos = deepcopy(float_pd_joint_pos)
160
+ float_pd_joint_delta_pos.use_delta = True
161
+ float_pd_joint_delta_pos.normalize_action = True
162
+ float_pd_joint_delta_pos.lower = -0.1
163
+ float_pd_joint_delta_pos.upper = 0.1
164
+
165
+ return dict(
166
+ pd_joint_pos=dict(
167
+ root=float_pd_joint_pos,
168
+ hand=hand_joint_pos,
169
+ fingers=fingers_joint_pos,
170
+ ),
171
+ pd_joint_delta_pos=dict(
172
+ root=float_pd_joint_delta_pos,
173
+ hand=hand_joint_delta_pos,
174
+ fingers=fingers_joint_delta_pos,
175
+ ),
176
+ )
@@ -181,6 +181,7 @@ class Panda(BaseAgent):
181
181
  stiffness=self.gripper_stiffness,
182
182
  damping=self.gripper_damping,
183
183
  force_limit=self.gripper_force_limit,
184
+ mimic={"panda_finger_joint2": {"joint": "panda_finger_joint1"}},
184
185
  )
185
186
 
186
187
  controller_configs = dict(