kuavo-humanoid-sdk 1.2.2__20250922181216-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 kuavo-humanoid-sdk might be problematic. Click here for more details.
- kuavo_humanoid_sdk/__init__.py +6 -0
- kuavo_humanoid_sdk/common/logger.py +45 -0
- kuavo_humanoid_sdk/interfaces/__init__.py +4 -0
- kuavo_humanoid_sdk/interfaces/data_types.py +276 -0
- kuavo_humanoid_sdk/interfaces/end_effector.py +62 -0
- kuavo_humanoid_sdk/interfaces/robot.py +22 -0
- kuavo_humanoid_sdk/interfaces/robot_info.py +56 -0
- kuavo_humanoid_sdk/kuavo/__init__.py +11 -0
- kuavo_humanoid_sdk/kuavo/core/audio.py +32 -0
- kuavo_humanoid_sdk/kuavo/core/core.py +612 -0
- kuavo_humanoid_sdk/kuavo/core/dex_hand_control.py +114 -0
- kuavo_humanoid_sdk/kuavo/core/leju_claw_control.py +67 -0
- kuavo_humanoid_sdk/kuavo/core/ros/audio.py +92 -0
- kuavo_humanoid_sdk/kuavo/core/ros/control.py +1309 -0
- kuavo_humanoid_sdk/kuavo/core/ros/observation.py +94 -0
- kuavo_humanoid_sdk/kuavo/core/ros/param.py +183 -0
- kuavo_humanoid_sdk/kuavo/core/ros/sat_utils.py +103 -0
- kuavo_humanoid_sdk/kuavo/core/ros/state.py +605 -0
- kuavo_humanoid_sdk/kuavo/core/ros/tools.py +219 -0
- kuavo_humanoid_sdk/kuavo/core/ros/vision.py +234 -0
- kuavo_humanoid_sdk/kuavo/core/ros_env.py +237 -0
- kuavo_humanoid_sdk/kuavo/dexterous_hand.py +201 -0
- kuavo_humanoid_sdk/kuavo/leju_claw.py +235 -0
- kuavo_humanoid_sdk/kuavo/robot.py +465 -0
- kuavo_humanoid_sdk/kuavo/robot_arm.py +210 -0
- kuavo_humanoid_sdk/kuavo/robot_audio.py +39 -0
- kuavo_humanoid_sdk/kuavo/robot_head.py +50 -0
- kuavo_humanoid_sdk/kuavo/robot_info.py +113 -0
- kuavo_humanoid_sdk/kuavo/robot_observation.py +64 -0
- kuavo_humanoid_sdk/kuavo/robot_state.py +299 -0
- kuavo_humanoid_sdk/kuavo/robot_tool.py +82 -0
- kuavo_humanoid_sdk/kuavo/robot_vision.py +83 -0
- kuavo_humanoid_sdk/kuavo_strategy/__init__.py +2 -0
- kuavo_humanoid_sdk/kuavo_strategy/grasp_box/grasp_box_strategy.py +1126 -0
- kuavo_humanoid_sdk/kuavo_strategy/kuavo_strategy.py +104 -0
- kuavo_humanoid_sdk/msg/__init__.py +4 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/__init__.py +7 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_AprilTagDetection.py +306 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_AprilTagDetectionArray.py +437 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_JoySticks.py +191 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_Metadata.py +199 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_RobotActionState.py +112 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_TFArray.py +323 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/__init__.py +48 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_armHandPose.py +160 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_armHandPoseFree.py +171 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_armPoseWithTimeStamp.py +168 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_armTargetPoses.py +151 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_bezierCurveCubicPoint.py +178 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_dexhandCommand.py +229 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_dexhandTouchState.py +256 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_endEffectorData.py +227 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_footPose.py +123 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_footPoseTargetTrajectories.py +301 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_footPoses.py +149 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_fullBodyTargetTrajectories.py +258 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_gaitTimeName.py +147 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_gestureInfo.py +218 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_gestureTask.py +149 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_handPose.py +136 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_headBodyPose.py +145 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_ikSolveError.py +171 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_ikSolveParam.py +140 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_imuData.py +165 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_jointBezierTrajectory.py +201 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_jointCmd.py +390 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_jointData.py +205 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_lejuClawCommand.py +320 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_lejuClawState.py +341 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_motorParam.py +122 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_planArmState.py +120 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_questJoySticks.py +191 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_qv.py +121 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_robotArmQVVD.py +177 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_robotHandPosition.py +225 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_robotHeadMotionData.py +128 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_robotState.py +222 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_sensorsData.py +495 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_switchGaitByName.py +200 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_touchSensorStatus.py +162 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_twoArmHandPose.py +272 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_twoArmHandPoseCmd.py +315 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_twoArmHandPoseCmdFree.py +338 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_twoArmHandPoseFree.py +299 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_yoloDetection.py +251 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_yoloOutputData.py +168 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_ExecuteArmAction.py +281 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_RepublishTFs.py +373 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_SetJoyTopic.py +282 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_SpeechSynthesis.py +270 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/__init__.py +29 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_changeArmCtrlMode.py +275 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_changeArmCtrlModeKuavo.py +236 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_changeMotorParam.py +299 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_changeTorsoCtrlMode.py +274 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_controlLejuClaw.py +408 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_enableHandTouchSensor.py +304 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_fkSrv.py +394 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_footPoseTargetTrajectoriesSrv.py +409 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_gestureExecute.py +339 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_gestureExecuteState.py +257 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_gestureList.py +418 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_getCurrentGaitName.py +253 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_getMotorParam.py +299 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_handForceLevel.py +330 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_jointMoveTo.py +302 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_planArmTrajectoryBezierCurve.py +421 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_planArmTrajectoryCubicSpline.py +490 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_playmusic.py +268 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_setHwIntialState.py +304 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_setMmCtrlFrame.py +273 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_setMotorEncoderRoundService.py +283 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_setTagId.py +275 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_singleStepControl.py +444 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_twoArmHandPoseCmdFreeSrv.py +716 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_twoArmHandPoseCmdSrv.py +662 -0
- kuavo_humanoid_sdk/msg/motion_capture_ik/__init__.py +7 -0
- kuavo_humanoid_sdk/msg/ocs2_msgs/__init__.py +7 -0
- kuavo_humanoid_sdk/msg/ocs2_msgs/msg/__init__.py +12 -0
- kuavo_humanoid_sdk/msg/ocs2_msgs/msg/_constraint.py +142 -0
- kuavo_humanoid_sdk/msg/ocs2_msgs/msg/_controller_data.py +121 -0
- kuavo_humanoid_sdk/msg/ocs2_msgs/msg/_lagrangian_metrics.py +148 -0
- kuavo_humanoid_sdk/msg/ocs2_msgs/msg/_mode_schedule.py +150 -0
- kuavo_humanoid_sdk/msg/ocs2_msgs/msg/_mpc_flattened_controller.py +666 -0
- kuavo_humanoid_sdk/msg/ocs2_msgs/msg/_mpc_input.py +122 -0
- kuavo_humanoid_sdk/msg/ocs2_msgs/msg/_mpc_observation.py +209 -0
- kuavo_humanoid_sdk/msg/ocs2_msgs/msg/_mpc_performance_indices.py +140 -0
- kuavo_humanoid_sdk/msg/ocs2_msgs/msg/_mpc_solver_data.py +886 -0
- kuavo_humanoid_sdk/msg/ocs2_msgs/msg/_mpc_state.py +122 -0
- kuavo_humanoid_sdk/msg/ocs2_msgs/msg/_mpc_target_trajectories.py +239 -0
- kuavo_humanoid_sdk/msg/ocs2_msgs/msg/_multiplier.py +148 -0
- kuavo_humanoid_sdk/msg/ocs2_msgs/srv/__init__.py +1 -0
- kuavo_humanoid_sdk/msg/ocs2_msgs/srv/_reset.py +376 -0
- kuavo_humanoid_sdk-1.2.2.dist-info/METADATA +291 -0
- kuavo_humanoid_sdk-1.2.2.dist-info/RECORD +137 -0
- kuavo_humanoid_sdk-1.2.2.dist-info/WHEEL +6 -0
- kuavo_humanoid_sdk-1.2.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# coding: utf-8
|
|
3
|
+
from typing import Tuple
|
|
4
|
+
from kuavo_humanoid_sdk.interfaces.end_effector import EndEffector
|
|
5
|
+
from kuavo_humanoid_sdk.interfaces.data_types import EndEffectorSide, EndEffectorState, KuavoDexHandTouchState
|
|
6
|
+
from kuavo_humanoid_sdk.kuavo.core.dex_hand_control import DexHandControl
|
|
7
|
+
from kuavo_humanoid_sdk.kuavo.core.ros.state import KuavoRobotStateCore
|
|
8
|
+
|
|
9
|
+
class DexterousHand(EndEffector):
|
|
10
|
+
"""普通灵巧手控制类"""
|
|
11
|
+
def __init__(self):
|
|
12
|
+
joint_names = ['l_thumb', 'l_thumb_aux', 'l_index', 'l_middle', 'l_ring', 'l_pinky',
|
|
13
|
+
'r_thumb', 'r_thumb_aux', 'r_index', 'r_middle', 'r_ring', 'r_pinky',]
|
|
14
|
+
super().__init__(joint_names=joint_names)
|
|
15
|
+
self.dex_hand_control = DexHandControl()
|
|
16
|
+
self._rb_state = KuavoRobotStateCore()
|
|
17
|
+
|
|
18
|
+
def control(self, target_positions:list, target_velocities:list=None, target_torques:list=None)->bool:
|
|
19
|
+
"""控制灵巧手的位置。
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
target_positions (list): 所有手指关节的目标位置列表,长度必须为12(每只手6个手指关节),范围 => [0.0 ~ 100.0]
|
|
23
|
+
target_velocities (list, optional): 不支持。默认为None。
|
|
24
|
+
target_torques (list, optional): 不支持。默认为None。
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
bool: 如果控制成功返回 True,否则返回 False。
|
|
28
|
+
|
|
29
|
+
Note:
|
|
30
|
+
target_velocities 和 target_torques 参数暂不支持。
|
|
31
|
+
"""
|
|
32
|
+
if len(target_positions) != self.joint_count():
|
|
33
|
+
raise ValueError(f"Target positions must have the same length as joint names {len(target_positions)} != {self.joint_count()}")
|
|
34
|
+
|
|
35
|
+
q = [max(0, min(100, pos if isinstance(pos, int) else int(pos))) for pos in target_positions]
|
|
36
|
+
|
|
37
|
+
# control the hand
|
|
38
|
+
return self.dex_hand_control.control(target_positions=q, side=EndEffectorSide.BOTH)
|
|
39
|
+
|
|
40
|
+
def control_right(self, target_positions:list, target_velocities:list=None, target_torques:list=None)->bool:
|
|
41
|
+
"""控制右手灵巧手。
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
target_positions (list): 右手关节的目标位置 [0 ~ 100],长度必须为6
|
|
45
|
+
target_velocities (list, optional): 不支持。默认为None。
|
|
46
|
+
target_torques (list, optional): 不支持。默认为None。
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
bool: 如果控制成功返回True,否则返回False。
|
|
50
|
+
|
|
51
|
+
Raises:
|
|
52
|
+
ValueError: 如果目标位置长度与关节数不匹配或值超出[0,100]范围
|
|
53
|
+
|
|
54
|
+
Note:
|
|
55
|
+
target_velocities 和 target_torques 参数暂不支持。
|
|
56
|
+
"""
|
|
57
|
+
if len(target_positions) != (self.joint_count()/2):
|
|
58
|
+
raise ValueError(f"Target positions must have the same length as joint names {len(target_positions)} != {self.joint_count()/2}.")
|
|
59
|
+
|
|
60
|
+
q = [max(0, min(100, pos if isinstance(pos, int) else int(pos))) for pos in target_positions]
|
|
61
|
+
|
|
62
|
+
return self.dex_hand_control.control(target_positions=q, side=EndEffectorSide.RIGHT)
|
|
63
|
+
|
|
64
|
+
def control_left(self, target_positions:list, target_velocities:list=None, target_torques:list=None)->bool:
|
|
65
|
+
"""控制左手灵巧手。
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
target_positions (list): 左手关节的目标位置 [0 ~ 100],长度必须为6
|
|
69
|
+
target_velocities (list, optional): 不支持。默认为None。
|
|
70
|
+
target_torques (list, optional): 不支持。默认为None。
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
bool: 如果控制成功返回True,否则返回False。
|
|
74
|
+
|
|
75
|
+
Raises:
|
|
76
|
+
ValueError: 如果目标位置长度与关节数不匹配或值超出[0,100]范围
|
|
77
|
+
|
|
78
|
+
Note:
|
|
79
|
+
target_velocities 和 target_torques 参数不支持。
|
|
80
|
+
"""
|
|
81
|
+
if len(target_positions) != (self.joint_count()/2):
|
|
82
|
+
raise ValueError(f"Target positions must have the same length as joint names {len(target_positions)} != {self.joint_count()/2}.")
|
|
83
|
+
|
|
84
|
+
q = [max(0, min(100, pos if isinstance(pos, int) else int(pos))) for pos in target_positions]
|
|
85
|
+
|
|
86
|
+
return self.dex_hand_control.control(target_positions=q, side=EndEffectorSide.LEFT)
|
|
87
|
+
|
|
88
|
+
def open(self, side: EndEffectorSide=EndEffectorSide.BOTH)->bool:
|
|
89
|
+
"""通过将所有关节位置设置为 0 来张开灵巧手。
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
side (EndEffectorSide, optional): 要打开的手。默认为 :attr:`EndEffectorSide.BOTH`。 \n
|
|
93
|
+
可以是 :attr:`EndEffectorSide.LEFT`、:attr:`EndEffectorSide.RIGHT` 或 :attr:`EndEffectorSide.BOTH`。
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
bool: 如果打开命令发送成功返回True,否则返回False。
|
|
97
|
+
"""
|
|
98
|
+
zero_pos = [0]*self.joint_count()
|
|
99
|
+
if side == EndEffectorSide.LEFT:
|
|
100
|
+
return self.dex_hand_control.control(target_positions=zero_pos[:len(zero_pos)//2], side=EndEffectorSide.LEFT)
|
|
101
|
+
elif side == EndEffectorSide.RIGHT:
|
|
102
|
+
return self.dex_hand_control.control(target_positions=zero_pos[len(zero_pos)//2:], side=EndEffectorSide.RIGHT)
|
|
103
|
+
else:
|
|
104
|
+
return self.dex_hand_control.control(target_positions=zero_pos, side=EndEffectorSide.BOTH)
|
|
105
|
+
|
|
106
|
+
def make_gesture(self, l_gesture_name: str, r_gesture_name: str)->bool:
|
|
107
|
+
"""为双手做预定义的手势。
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
l_gesture_name (str): 左手手势的名称。None表示跳过左手。
|
|
111
|
+
r_gesture_name (str): 右手手势的名称。None表示跳过右手。
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
bool: 如果手势命令发送成功返回True,否则返回False。
|
|
115
|
+
|
|
116
|
+
Note:
|
|
117
|
+
手势示例:'fist'、'ok'、'thumbs_up'、'666'等...
|
|
118
|
+
"""
|
|
119
|
+
gesture = []
|
|
120
|
+
if l_gesture_name is not None:
|
|
121
|
+
gesture.append({'gesture_name':l_gesture_name, 'hand_side':EndEffectorSide.LEFT})
|
|
122
|
+
self.dex_hand_control.make_gestures(gesture)
|
|
123
|
+
if r_gesture_name is not None:
|
|
124
|
+
gesture.append({'gesture_name':r_gesture_name, 'hand_side':EndEffectorSide.RIGHT})
|
|
125
|
+
self.dex_hand_control.make_gestures(gesture)
|
|
126
|
+
return True
|
|
127
|
+
def get_gesture_names(self)->list:
|
|
128
|
+
"""获取所有手势的名称。
|
|
129
|
+
|
|
130
|
+
Returns:
|
|
131
|
+
list: 手势名称列表。
|
|
132
|
+
例如:['fist', 'ok', 'thumbs_up', '666', 'number_1', 'number_2', 'number_3', ... ], 如果没有手势则返回 None。
|
|
133
|
+
"""
|
|
134
|
+
return self.dex_hand_control.get_gesture_names()
|
|
135
|
+
|
|
136
|
+
def get_state(self)->Tuple[EndEffectorState, EndEffectorState]:
|
|
137
|
+
"""获取灵巧手的状态。
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
Tuple[EndEffectorState, EndEffectorState]: 灵巧手的状态。
|
|
141
|
+
"""
|
|
142
|
+
return self._rb_state.eef_state
|
|
143
|
+
|
|
144
|
+
def get_position(self)->Tuple[list, list]:
|
|
145
|
+
"""获取灵巧手的位置。
|
|
146
|
+
|
|
147
|
+
Returns:
|
|
148
|
+
Tuple[list, list]: 灵巧手的位置。
|
|
149
|
+
"""
|
|
150
|
+
state = self._rb_state.eef_state
|
|
151
|
+
return (state[0].position, state[1].position)
|
|
152
|
+
|
|
153
|
+
def get_velocity(self)->Tuple[list, list]:
|
|
154
|
+
"""获取灵巧手的速度。
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
Tuple[list, list]: 灵巧手的速度。
|
|
158
|
+
"""
|
|
159
|
+
state = self._rb_state.eef_state
|
|
160
|
+
return (state[0].velocity, state[1].velocity)
|
|
161
|
+
|
|
162
|
+
def get_effort(self)->Tuple[list, list]:
|
|
163
|
+
"""获取灵巧手的力。
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
Tuple[list, list]: 灵巧手的力。
|
|
167
|
+
|
|
168
|
+
Note:
|
|
169
|
+
每个手指的范围为0 ~ 100。表示最大电机电流的分数,绝对数值。
|
|
170
|
+
最大电机电流为600mA,换句话说,100。
|
|
171
|
+
"""
|
|
172
|
+
state = self._rb_state.eef_state
|
|
173
|
+
return (state[0].effort, state[1].effort)
|
|
174
|
+
|
|
175
|
+
def get_grasping_state(self)->Tuple[EndEffectorState.GraspingState, EndEffectorState.GraspingState]:
|
|
176
|
+
"""获取灵巧手的抓取状态。
|
|
177
|
+
|
|
178
|
+
Note:
|
|
179
|
+
该功能尚未实现。
|
|
180
|
+
|
|
181
|
+
Returns:
|
|
182
|
+
Tuple[EndEffectorState.GraspingState, EndEffectorState.GraspingState]: 灵巧手的抓取状态。
|
|
183
|
+
"""
|
|
184
|
+
raise NotImplementedError("This function is not implemented yet")
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
class TouchDexterousHand(DexterousHand):
|
|
188
|
+
"""触觉灵巧手控制类,继承自普通灵巧手控制类,可调用普通灵巧手控制类中的所有方法"""
|
|
189
|
+
def __init__(self):
|
|
190
|
+
super().__init__()
|
|
191
|
+
|
|
192
|
+
def get_touch_state(self)-> Tuple[KuavoDexHandTouchState, KuavoDexHandTouchState]:
|
|
193
|
+
"""获取灵巧手的触觉状态。
|
|
194
|
+
|
|
195
|
+
Warning:
|
|
196
|
+
该功能仅在触觉灵巧手上可用。
|
|
197
|
+
|
|
198
|
+
Returns:
|
|
199
|
+
Tuple[KuavoDexHandTouchState, KuavoDexHandTouchState]
|
|
200
|
+
"""
|
|
201
|
+
return self._rb_state.dexhand_touch_state
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# coding: utf-8
|
|
3
|
+
import time
|
|
4
|
+
from typing import Tuple
|
|
5
|
+
from kuavo_humanoid_sdk.interfaces.end_effector import EndEffector
|
|
6
|
+
from kuavo_humanoid_sdk.interfaces.data_types import EndEffectorSide, EndEffectorState
|
|
7
|
+
from kuavo_humanoid_sdk.kuavo.core.leju_claw_control import LejuClawControl
|
|
8
|
+
from kuavo_humanoid_sdk.kuavo.core.ros.state import KuavoRobotStateCore
|
|
9
|
+
|
|
10
|
+
class LejuClaw(EndEffector):
|
|
11
|
+
def __init__(self):
|
|
12
|
+
super().__init__(joint_names=['left_claw', 'right_claw'])
|
|
13
|
+
self.leju_claw_control = LejuClawControl()
|
|
14
|
+
self._rb_state = KuavoRobotStateCore()
|
|
15
|
+
|
|
16
|
+
def control(self, target_positions: list, target_velocities:list=None, target_torques: list=None)->bool:
|
|
17
|
+
"""控制机器人夹爪抓取。
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
target_positions (list): 夹爪的目标位置。\n
|
|
21
|
+
target_velocities (list, optional): 夹爪的目标速度。如果为None,将使用默认值[90, 90]。\n
|
|
22
|
+
target_torques (list, optional): 夹爪的目标扭矩。如果为None,将使用默认值[1.0, 1.0]。\n
|
|
23
|
+
|
|
24
|
+
Note:
|
|
25
|
+
target_positions、target_velocities 和 target_torques 必须是长度为`self.joint_count()`的列表。\n
|
|
26
|
+
调用此函数后,可以调用 :meth:`LejuClaw.wait_for_finish` 等待夹爪到达目标位置。
|
|
27
|
+
|
|
28
|
+
Warning:
|
|
29
|
+
如果夹爪仍在执行上一个命令(运动未结束),这个请求可能会被丢弃。
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
bool: 如果夹爪成功发送命令返回True,否则返回False。
|
|
33
|
+
"""
|
|
34
|
+
if target_positions is None or len(target_positions) != self.joint_count():
|
|
35
|
+
raise ValueError("Target positions must be provided.")
|
|
36
|
+
|
|
37
|
+
target_positions = [max(0.0, min(100.0, pos)) for pos in target_positions]
|
|
38
|
+
if target_velocities is None:
|
|
39
|
+
target_velocities = [90, 90]
|
|
40
|
+
else:
|
|
41
|
+
if len(target_velocities) != self.joint_count():
|
|
42
|
+
raise ValueError("Target velocities must be a list of length 2.")
|
|
43
|
+
target_velocities = [max(0.0, min(100.0, vel)) for vel in target_velocities]
|
|
44
|
+
|
|
45
|
+
if target_torques is None:
|
|
46
|
+
target_torques = [1.0, 1.0]
|
|
47
|
+
else:
|
|
48
|
+
if len(target_torques) != self.joint_count():
|
|
49
|
+
raise ValueError("Target torques must be a list of length 2.")
|
|
50
|
+
target_torques = [max(0.0, min(10.0, torque)) for torque in target_torques]
|
|
51
|
+
|
|
52
|
+
return self.leju_claw_control.control(target_positions, target_velocities, target_torques, EndEffectorSide.BOTH)
|
|
53
|
+
|
|
54
|
+
def control_left(self, target_positions:list, target_velocities:list=None, target_torques:list=None)->bool:
|
|
55
|
+
"""控制机器人左夹爪抓取。
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
target_positions (list): 左夹爪的目标位置。\n
|
|
59
|
+
target_velocities (list, optional): 左夹爪的目标速度。如果为None,将使用默认值[90, 90]。\n
|
|
60
|
+
target_torques (list, optional): 左夹爪的目标扭矩。如果为None,将使用默认值[1.0, 1.0]。\n
|
|
61
|
+
|
|
62
|
+
Note:
|
|
63
|
+
target_positions、target_velocities 和 target_torques 必须是长度为`self.joint_count()/2`的列表。\n
|
|
64
|
+
调用此函数后,可以调用 :meth:`LejuClaw.wait_for_finish` 等待夹爪到达目标位置。
|
|
65
|
+
|
|
66
|
+
Warning:
|
|
67
|
+
如果夹爪仍在执行上一个命令(运动未结束),这个请求可能会被丢弃。
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
bool: 如果夹爪成功发送命令返回True,否则返回False。
|
|
71
|
+
"""
|
|
72
|
+
if target_positions is None:
|
|
73
|
+
raise ValueError("Target positions must be provided.")
|
|
74
|
+
|
|
75
|
+
for data in [target_positions, target_velocities, target_torques]:
|
|
76
|
+
if data is not None and len(data) != self.joint_count()/2:
|
|
77
|
+
raise ValueError(f"Target data must be a list of length {self.joint_count()/2}.")
|
|
78
|
+
|
|
79
|
+
q = max(0.0, min(100.0, target_positions[0]))
|
|
80
|
+
|
|
81
|
+
if target_velocities is not None:
|
|
82
|
+
v = max(0.0, min(100.0, target_velocities[0]))
|
|
83
|
+
else:
|
|
84
|
+
v = 90
|
|
85
|
+
|
|
86
|
+
if target_torques is not None:
|
|
87
|
+
tau = max(0.0, min(10.0, target_torques[0]))
|
|
88
|
+
else:
|
|
89
|
+
tau = 1.0
|
|
90
|
+
|
|
91
|
+
return self.leju_claw_control.control([q], [v], [tau], EndEffectorSide.LEFT)
|
|
92
|
+
|
|
93
|
+
def control_right(self, target_positions:list, target_velocities:list=None, target_torques:list=None)->bool:
|
|
94
|
+
"""控制机器人右夹爪抓取。
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
target_positions (list): 右夹爪的目标位置。\n
|
|
98
|
+
target_velocities (list, optional): 右夹爪的目标速度。如果为None,将使用默认值[90, 90]。\n
|
|
99
|
+
target_torques (list, optional): 右夹爪的目标扭矩。如果为None,将使用默认值[1.0, 1.0]。\n
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
bool: 如果夹爪成功发送命令返回True,否则返回False。
|
|
103
|
+
|
|
104
|
+
Note:
|
|
105
|
+
target_positions、target_velocities 和 target_torques 必须是长度为`self.joint_count()/2`的列表。\n
|
|
106
|
+
调用此函数后,可以调用 :meth:`LejuClaw.wait_for_finish` 等待夹爪到达目标位置。
|
|
107
|
+
|
|
108
|
+
Warning:
|
|
109
|
+
If the claws are still in motion from a previous command, this request may be dropped.
|
|
110
|
+
"""
|
|
111
|
+
if target_positions is None:
|
|
112
|
+
raise ValueError("Target positions must be provided.")
|
|
113
|
+
|
|
114
|
+
for data in [target_positions, target_velocities, target_torques]:
|
|
115
|
+
if data is not None and len(data) != self.joint_count()/2:
|
|
116
|
+
raise ValueError(f"Target data must be a list of length {self.joint_count()/2}.")
|
|
117
|
+
|
|
118
|
+
q = max(0.0, min(100.0, target_positions[0]))
|
|
119
|
+
|
|
120
|
+
if target_velocities is not None:
|
|
121
|
+
v = max(0.0, min(100.0, target_velocities[0]))
|
|
122
|
+
else:
|
|
123
|
+
v = 90
|
|
124
|
+
|
|
125
|
+
if target_torques is not None:
|
|
126
|
+
tau = max(0.0, min(10.0, target_torques[0]))
|
|
127
|
+
else:
|
|
128
|
+
tau = 1.0
|
|
129
|
+
|
|
130
|
+
return self.leju_claw_control.control([q], [v], [tau], EndEffectorSide.RIGHT)
|
|
131
|
+
|
|
132
|
+
def open(self, side:EndEffectorSide=EndEffectorSide.BOTH)->bool:
|
|
133
|
+
"""控制夹爪释放/打开。
|
|
134
|
+
|
|
135
|
+
Note:
|
|
136
|
+
控制夹爪打开。 \n
|
|
137
|
+
调用此函数后,可以调用 :meth:`LejuClaw.wait_for_finish` 等待夹爪到达目标位置。
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
side (EndEffectorSide, optional): 要控制的夹爪侧(左/右或左右),默认为 :attr:`EndEffectorSide.BOTH` 。
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
bool: 如果夹爪成功发送命令返回True,否则返回False。
|
|
144
|
+
"""
|
|
145
|
+
return self.leju_claw_control.release(side)
|
|
146
|
+
|
|
147
|
+
def close(self, side:EndEffectorSide=EndEffectorSide.BOTH)->bool:
|
|
148
|
+
"""控制二指夹爪闭合/抓取。
|
|
149
|
+
|
|
150
|
+
Note:
|
|
151
|
+
控制二指夹爪闭合 \n
|
|
152
|
+
调用此函数后,可以调用 :meth:`LejuClaw.wait_for_finish` 等待二指夹爪到达目标位置 \n
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
side (EndEffectorSide, optional): 要控制的二指夹爪侧(左/右或左右),默认为 :attr:`EndEffectorState.BOTH`
|
|
156
|
+
|
|
157
|
+
Returns:
|
|
158
|
+
bool: 如果二指夹爪闭合命令发送成功返回 True, 否则返回 False。 \n
|
|
159
|
+
|
|
160
|
+
Warning:
|
|
161
|
+
二指夹爪的闭合范围为 [0, 100],其中 0 表示完全闭合,100 表示完全打开。
|
|
162
|
+
"""
|
|
163
|
+
return self.leju_claw_control.control(position=[100, 100], velocity=[90, 90], torque=[1.0, 1.0], side=side)
|
|
164
|
+
|
|
165
|
+
def get_grasping_state(self)->Tuple[EndEffectorState.GraspingState, EndEffectorState.GraspingState]:
|
|
166
|
+
"""获取夹爪的抓取状态。
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
Tuple[EndEffectorState.GraspingState, EndEffectorState.GraspingState]: 夹爪的抓取状态。
|
|
170
|
+
"""
|
|
171
|
+
return self._rb_state.eef_state.state
|
|
172
|
+
|
|
173
|
+
def get_position(self)->Tuple[list, list]:
|
|
174
|
+
"""获取夹爪的位置。
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
Tuple[list, list]: 夹爪的位置,范围 [0.0, 100.0]。
|
|
178
|
+
"""
|
|
179
|
+
claw_state = self._rb_state.eef_state
|
|
180
|
+
return (claw_state[0].position, claw_state[1].position)
|
|
181
|
+
|
|
182
|
+
def get_velocity(self)->Tuple[list, list]:
|
|
183
|
+
"""获取夹爪的速度。
|
|
184
|
+
|
|
185
|
+
Returns:
|
|
186
|
+
Tuple[list, list]: 夹爪的速度。
|
|
187
|
+
"""
|
|
188
|
+
claw_state = self._rb_state.eef_state
|
|
189
|
+
return (claw_state[0].velocity, claw_state[1].velocity)
|
|
190
|
+
|
|
191
|
+
def get_effort(self)->Tuple[list, list]:
|
|
192
|
+
"""获取夹爪的力。
|
|
193
|
+
|
|
194
|
+
Returns:
|
|
195
|
+
Tuple[list, list]: 夹爪的力。
|
|
196
|
+
"""
|
|
197
|
+
claw_state = self._rb_state.eef_state
|
|
198
|
+
return (claw_state[0].effort, claw_state[1].effort)
|
|
199
|
+
|
|
200
|
+
def get_state(self)->Tuple[EndEffectorState, EndEffectorState]:
|
|
201
|
+
"""获取夹爪的状态。
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
Tuple[EndEffectorState, EndEffectorState]: 夹爪的状态。
|
|
205
|
+
- position: 夹爪的位置,范围 [0.0, 100.0]。
|
|
206
|
+
- velocity: 夹爪的速度。
|
|
207
|
+
- effort: 夹爪的力。
|
|
208
|
+
- state: 夹爪的抓取状态。
|
|
209
|
+
"""
|
|
210
|
+
return self._rb_state.eef_state
|
|
211
|
+
|
|
212
|
+
def wait_for_finish(self, side: EndEffectorSide=EndEffectorSide.BOTH, timeout:float=2.5):
|
|
213
|
+
"""等待夹爪运动完成。
|
|
214
|
+
|
|
215
|
+
Args:
|
|
216
|
+
side (EndEffectorSide, optional): 要等待的夹爪侧(左/右或左右),默认为 :attr:`EndEffectorSide.BOTH` 。
|
|
217
|
+
timeout (float, optional): 等待超时时间,默认为 2.5 秒。
|
|
218
|
+
|
|
219
|
+
Returns:
|
|
220
|
+
bool: 如果运动在超时前完成返回True,否则返回False。
|
|
221
|
+
"""
|
|
222
|
+
start_time = time.time()
|
|
223
|
+
while time.time() - start_time < timeout:
|
|
224
|
+
if side == EndEffectorSide.BOTH:
|
|
225
|
+
if self._rb_state.eef_state[0].state >= EndEffectorState.GraspingState.REACHED and \
|
|
226
|
+
self._rb_state.eef_state[1].state >= EndEffectorState.GraspingState.REACHED:
|
|
227
|
+
return True
|
|
228
|
+
elif side == EndEffectorSide.LEFT:
|
|
229
|
+
if self._rb_state.eef_state[0].state >= EndEffectorState.GraspingState.REACHED:
|
|
230
|
+
return True
|
|
231
|
+
elif side == EndEffectorSide.RIGHT:
|
|
232
|
+
if self._rb_state.eef_state[1].state >= EndEffectorState.GraspingState.REACHED:
|
|
233
|
+
return True
|
|
234
|
+
time.sleep(0.1)
|
|
235
|
+
return False
|