kuavo-humanoid-sdk 1.1.3a1252__py3-none-any.whl → 1.1.6__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/interfaces/data_types.py +0 -46
- kuavo_humanoid_sdk/kuavo/__init__.py +0 -3
- kuavo_humanoid_sdk/kuavo/core/core.py +6 -18
- kuavo_humanoid_sdk/kuavo/core/ros/control.py +19 -645
- kuavo_humanoid_sdk/kuavo/core/ros/param.py +4 -142
- kuavo_humanoid_sdk/kuavo/core/ros/state.py +15 -329
- kuavo_humanoid_sdk/kuavo/core/ros_env.py +1 -229
- kuavo_humanoid_sdk/kuavo/dexterous_hand.py +2 -6
- kuavo_humanoid_sdk/kuavo/leju_claw.py +2 -6
- kuavo_humanoid_sdk/kuavo/robot.py +22 -43
- kuavo_humanoid_sdk/kuavo/robot_info.py +2 -7
- kuavo_humanoid_sdk/kuavo/robot_state.py +2 -6
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/__init__.py +0 -7
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/__init__.py +0 -4
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_playmusic.py +20 -26
- kuavo_humanoid_sdk/msg/motion_capture_ik/msg/__init__.py +9 -0
- kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/msg/_armHandPose.py +2 -2
- kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/msg/_handPose.py +2 -2
- kuavo_humanoid_sdk/msg/motion_capture_ik/msg/_headBodyPose.py +145 -0
- kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/msg/_ikSolveError.py +13 -13
- kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/msg/_ikSolveParam.py +2 -2
- kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/msg/_robotArmQVVD.py +2 -2
- kuavo_humanoid_sdk/msg/motion_capture_ik/msg/_robotHandPosition.py +225 -0
- kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/msg/_twoArmHandPose.py +13 -13
- kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/msg/_twoArmHandPoseCmd.py +15 -15
- kuavo_humanoid_sdk/msg/motion_capture_ik/srv/__init__.py +4 -0
- kuavo_humanoid_sdk/msg/{kuavo_msgs/srv/_SpeechSynthesis.py → motion_capture_ik/srv/_changeArmCtrlMode.py} +98 -93
- kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/srv/_changeArmCtrlModeKuavo.py +5 -5
- kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/srv/_fkSrv.py +13 -13
- kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/srv/_twoArmHandPoseCmdSrv.py +23 -23
- {kuavo_humanoid_sdk-1.1.3a1252.dist-info → kuavo_humanoid_sdk-1.1.6.dist-info}/METADATA +1 -2
- {kuavo_humanoid_sdk-1.1.3a1252.dist-info → kuavo_humanoid_sdk-1.1.6.dist-info}/RECORD +34 -39
- kuavo_humanoid_sdk/common/global_config.py +0 -16
- kuavo_humanoid_sdk/common/websocket_kuavo_sdk.py +0 -23
- kuavo_humanoid_sdk/kuavo/core/audio.py +0 -36
- kuavo_humanoid_sdk/kuavo/core/ros/audio.py +0 -176
- kuavo_humanoid_sdk/kuavo/core/ros/tools.py +0 -158
- kuavo_humanoid_sdk/kuavo/core/ros/vision.py +0 -522
- kuavo_humanoid_sdk/kuavo/robot_audio.py +0 -39
- kuavo_humanoid_sdk/kuavo/robot_tool.py +0 -62
- kuavo_humanoid_sdk/kuavo/robot_vision.py +0 -90
- {kuavo_humanoid_sdk-1.1.3a1252.dist-info → kuavo_humanoid_sdk-1.1.6.dist-info}/WHEEL +0 -0
- {kuavo_humanoid_sdk-1.1.3a1252.dist-info → kuavo_humanoid_sdk-1.1.6.dist-info}/top_level.txt +0 -0
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
try:
|
|
3
|
-
import rospy
|
|
4
|
-
except ImportError:
|
|
5
|
-
pass
|
|
1
|
+
import rospy
|
|
6
2
|
import json
|
|
7
3
|
import xml.etree.ElementTree as ET
|
|
8
4
|
from kuavo_humanoid_sdk.common.logger import SDKLogger
|
|
9
|
-
|
|
5
|
+
|
|
10
6
|
# End effector types
|
|
11
7
|
class EndEffectorType:
|
|
12
8
|
QIANGNAO = "qiangnao"
|
|
@@ -68,126 +64,7 @@ class RosParameter:
|
|
|
68
64
|
return None
|
|
69
65
|
return rospy.get_param('/initial_state')
|
|
70
66
|
|
|
71
|
-
|
|
72
|
-
class RosParamWebsocket:
|
|
73
|
-
def __init__(self):
|
|
74
|
-
self.websocket = WebSocketKuavoSDK()
|
|
75
|
-
if not self.websocket.client.is_connected:
|
|
76
|
-
SDKLogger.error("Failed to connect to WebSocket server")
|
|
77
|
-
raise ConnectionError("Failed to connect to WebSocket server")
|
|
78
|
-
|
|
79
|
-
def robot_version(self)->str:
|
|
80
|
-
try:
|
|
81
|
-
param_service = roslibpy.Param(self.websocket.client, 'robot_version')
|
|
82
|
-
param = param_service.get()
|
|
83
|
-
if param is None:
|
|
84
|
-
SDKLogger.error("robot_version parameter not found")
|
|
85
|
-
return None
|
|
86
|
-
return param
|
|
87
|
-
except Exception as e:
|
|
88
|
-
SDKLogger.error(f"Failed to get robot_version: {e}")
|
|
89
|
-
return None
|
|
90
|
-
|
|
91
|
-
def arm_dof(self)->int:
|
|
92
|
-
try:
|
|
93
|
-
param_service = roslibpy.Param(self.websocket.client, 'armRealDof')
|
|
94
|
-
param = param_service.get()
|
|
95
|
-
if param is None:
|
|
96
|
-
SDKLogger.error("armRealDof parameter not found")
|
|
97
|
-
return None
|
|
98
|
-
return param
|
|
99
|
-
except Exception as e:
|
|
100
|
-
SDKLogger.error(f"Failed to get armRealDof: {e}")
|
|
101
|
-
return None
|
|
102
|
-
|
|
103
|
-
def head_dof(self)->int:
|
|
104
|
-
try:
|
|
105
|
-
param_service = roslibpy.Param(self.websocket.client, 'headRealDof')
|
|
106
|
-
param = param_service.get()
|
|
107
|
-
if param is None:
|
|
108
|
-
SDKLogger.error("headRealDof parameter not found")
|
|
109
|
-
return None
|
|
110
|
-
return param
|
|
111
|
-
except Exception as e:
|
|
112
|
-
SDKLogger.error(f"Failed to get headRealDof: {e}")
|
|
113
|
-
return None
|
|
114
|
-
|
|
115
|
-
def leg_dof(self)->int:
|
|
116
|
-
try:
|
|
117
|
-
param_service = roslibpy.Param(self.websocket.client, 'legRealDof')
|
|
118
|
-
param = param_service.get()
|
|
119
|
-
if param is None:
|
|
120
|
-
SDKLogger.error("legRealDof parameter not found")
|
|
121
|
-
return None
|
|
122
|
-
return param
|
|
123
|
-
except Exception as e:
|
|
124
|
-
SDKLogger.error(f"Failed to get legRealDof: {e}")
|
|
125
|
-
return None
|
|
126
|
-
|
|
127
|
-
def end_effector_type(self)->str:
|
|
128
|
-
try:
|
|
129
|
-
param_service = roslibpy.Param(self.websocket.client, 'end_effector_type')
|
|
130
|
-
param = param_service.get()
|
|
131
|
-
if param is None:
|
|
132
|
-
SDKLogger.error("end_effector_type parameter not found")
|
|
133
|
-
return None
|
|
134
|
-
return param
|
|
135
|
-
except Exception as e:
|
|
136
|
-
SDKLogger.error(f"Failed to get end_effector_type: {e}")
|
|
137
|
-
return None
|
|
138
|
-
|
|
139
|
-
def humanoid_description(self)->str:
|
|
140
|
-
try:
|
|
141
|
-
param_service = roslibpy.Param(self.websocket.client, 'humanoid_description')
|
|
142
|
-
param = param_service.get()
|
|
143
|
-
if param is None:
|
|
144
|
-
SDKLogger.error("humanoid_description parameter not found")
|
|
145
|
-
return None
|
|
146
|
-
return param
|
|
147
|
-
except Exception as e:
|
|
148
|
-
SDKLogger.error(f"Failed to get humanoid_description: {e}")
|
|
149
|
-
return None
|
|
150
|
-
|
|
151
|
-
def model_path(self)->str:
|
|
152
|
-
try:
|
|
153
|
-
param_service = roslibpy.Param(self.websocket.client, 'modelPath')
|
|
154
|
-
param = param_service.get()
|
|
155
|
-
if param is None:
|
|
156
|
-
SDKLogger.error("modelPath parameter not found")
|
|
157
|
-
return None
|
|
158
|
-
return param
|
|
159
|
-
except Exception as e:
|
|
160
|
-
SDKLogger.error(f"Failed to get modelPath: {e}")
|
|
161
|
-
return None
|
|
162
|
-
|
|
163
|
-
def kuavo_config(self)->str:
|
|
164
|
-
try:
|
|
165
|
-
param_service = roslibpy.Param(self.websocket.client, 'kuavo_configuration')
|
|
166
|
-
param = param_service.get()
|
|
167
|
-
if param is None:
|
|
168
|
-
SDKLogger.error("kuavo_configuration parameter not found")
|
|
169
|
-
return None
|
|
170
|
-
return param
|
|
171
|
-
except Exception as e:
|
|
172
|
-
SDKLogger.error(f"Failed to get kuavo_configuration: {e}")
|
|
173
|
-
return None
|
|
174
|
-
|
|
175
|
-
def initial_state(self)->str:
|
|
176
|
-
try:
|
|
177
|
-
param_service = roslibpy.Param(self.websocket.client, 'initial_state')
|
|
178
|
-
param = param_service.get()
|
|
179
|
-
if param is None:
|
|
180
|
-
SDKLogger.error("initial_state parameter not found")
|
|
181
|
-
return None
|
|
182
|
-
return param
|
|
183
|
-
except Exception as e:
|
|
184
|
-
SDKLogger.error(f"Failed to get initial_state: {e}")
|
|
185
|
-
return None
|
|
186
|
-
|
|
187
|
-
# if GlobalConfig.use_websocket:
|
|
188
|
-
# kuavo_ros_param = RosParamWebsocket()
|
|
189
|
-
# else:
|
|
190
|
-
# kuavo_ros_param = RosParameter()
|
|
67
|
+
kuavo_ros_param = RosParameter()
|
|
191
68
|
|
|
192
69
|
def joint_names()->dict:
|
|
193
70
|
leg_link_names = [
|
|
@@ -201,11 +78,6 @@ def joint_names()->dict:
|
|
|
201
78
|
head_link_names = [
|
|
202
79
|
'zhead_1_link', 'zhead_2_link'
|
|
203
80
|
]
|
|
204
|
-
if GlobalConfig.use_websocket:
|
|
205
|
-
kuavo_ros_param = RosParamWebsocket()
|
|
206
|
-
else:
|
|
207
|
-
kuavo_ros_param = RosParameter()
|
|
208
|
-
|
|
209
81
|
robot_desc = kuavo_ros_param.humanoid_description()
|
|
210
82
|
if robot_desc is None:
|
|
211
83
|
return None
|
|
@@ -263,11 +135,6 @@ kuavo_ros_info = None
|
|
|
263
135
|
|
|
264
136
|
def end_frames_names()->dict:
|
|
265
137
|
default = ["torso", "zarm_l7_link", "zarm_r7_link", "zarm_l4_link", "zarm_r4_link"]
|
|
266
|
-
if GlobalConfig.use_websocket:
|
|
267
|
-
kuavo_ros_param = RosParamWebsocket()
|
|
268
|
-
else:
|
|
269
|
-
kuavo_ros_param = RosParameter()
|
|
270
|
-
|
|
271
138
|
kuavo_json = kuavo_ros_param.kuavo_config()
|
|
272
139
|
if kuavo_json is None:
|
|
273
140
|
return default
|
|
@@ -287,11 +154,6 @@ def make_robot_param()->dict:
|
|
|
287
154
|
if kuavo_ros_info is not None:
|
|
288
155
|
return kuavo_ros_info
|
|
289
156
|
|
|
290
|
-
if GlobalConfig.use_websocket:
|
|
291
|
-
kuavo_ros_param = RosParamWebsocket()
|
|
292
|
-
else:
|
|
293
|
-
kuavo_ros_param = RosParameter()
|
|
294
|
-
|
|
295
157
|
kuavo_ros_info = {
|
|
296
158
|
'robot_version': kuavo_ros_param.robot_version(),
|
|
297
159
|
'arm_dof': kuavo_ros_param.arm_dof(),
|
|
@@ -312,4 +174,4 @@ def make_robot_param()->dict:
|
|
|
312
174
|
|
|
313
175
|
if __name__ == "__main__":
|
|
314
176
|
rospy.init_node("kuavo_ros_param_test")
|
|
315
|
-
print(make_robot_param())
|
|
177
|
+
print(make_robot_param())
|
|
@@ -1,24 +1,17 @@
|
|
|
1
|
-
import
|
|
1
|
+
import rospy
|
|
2
2
|
import copy
|
|
3
3
|
import time
|
|
4
4
|
from typing import Tuple
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
from kuavo_humanoid_sdk.msg.kuavo_msgs.msg import sensorsData, lejuClawState, gaitTimeName, dexhandTouchState
|
|
12
|
-
from kuavo_msgs.srv import changeArmCtrlMode, changeArmCtrlModeRequest, getCurrentGaitName, getCurrentGaitNameRequest
|
|
13
|
-
from kuavo_humanoid_sdk.msg.ocs2_msgs.msg import mpc_observation
|
|
14
|
-
except:
|
|
15
|
-
pass
|
|
16
|
-
|
|
5
|
+
from std_msgs.msg import Float64
|
|
6
|
+
from nav_msgs.msg import Odometry
|
|
7
|
+
from sensor_msgs.msg import JointState
|
|
8
|
+
from kuavo_humanoid_sdk.msg.kuavo_msgs.msg import sensorsData, lejuClawState, gaitTimeName, dexhandTouchState
|
|
9
|
+
from kuavo_msgs.srv import changeArmCtrlMode, changeArmCtrlModeRequest, getCurrentGaitName, getCurrentGaitNameRequest
|
|
10
|
+
from kuavo_humanoid_sdk.msg.ocs2_msgs.msg import mpc_observation
|
|
17
11
|
from kuavo_humanoid_sdk.interfaces.data_types import (KuavoImuData, KuavoJointData, KuavoOdometry,
|
|
18
12
|
KuavoArmCtrlMode, EndEffectorState, KuavoDexHandTouchState)
|
|
19
13
|
from kuavo_humanoid_sdk.kuavo.core.ros.param import make_robot_param, EndEffectorType
|
|
20
14
|
from kuavo_humanoid_sdk.common.logger import SDKLogger
|
|
21
|
-
from kuavo_humanoid_sdk.common.websocket_kuavo_sdk import WebSocketKuavoSDK
|
|
22
15
|
|
|
23
16
|
from collections import deque
|
|
24
17
|
from typing import Tuple, Optional
|
|
@@ -57,7 +50,6 @@ class GaitManager:
|
|
|
57
50
|
return "No_Gait"
|
|
58
51
|
return self._gait_time_names[-1][1]
|
|
59
52
|
|
|
60
|
-
|
|
61
53
|
class KuavoRobotStateCore:
|
|
62
54
|
_instance = None
|
|
63
55
|
|
|
@@ -250,10 +242,10 @@ class KuavoRobotStateCore:
|
|
|
250
242
|
self._gait_changed_callbacks.append(callback)
|
|
251
243
|
|
|
252
244
|
""" ------------------------------- callback ------------------------------- """
|
|
253
|
-
def _terrain_height_callback(self, msg)->None:
|
|
245
|
+
def _terrain_height_callback(self, msg:Float64)->None:
|
|
254
246
|
self._terrain_height = msg.data
|
|
255
247
|
|
|
256
|
-
def _sensors_data_raw_callback(self, msg)->None:
|
|
248
|
+
def _sensors_data_raw_callback(self, msg:sensorsData)->None:
|
|
257
249
|
# update imu data
|
|
258
250
|
self._imu_data = KuavoImuData(
|
|
259
251
|
gyro = (msg.imu_data.gyro.x, msg.imu_data.gyro.y, msg.imu_data.gyro.z),
|
|
@@ -269,7 +261,7 @@ class KuavoRobotStateCore:
|
|
|
269
261
|
acceleration = copy.deepcopy(msg.joint_data.joint_current if hasattr(msg.joint_data, 'joint_current') else msg.joint_data.joint_torque)
|
|
270
262
|
)
|
|
271
263
|
|
|
272
|
-
def _odom_callback(self, msg)->None:
|
|
264
|
+
def _odom_callback(self, msg:Odometry)->None:
|
|
273
265
|
# update odom data
|
|
274
266
|
self._odom_data = KuavoOdometry(
|
|
275
267
|
position = (msg.pose.pose.position.x, msg.pose.pose.position.y, msg.pose.pose.position.z),
|
|
@@ -278,7 +270,7 @@ class KuavoRobotStateCore:
|
|
|
278
270
|
angular = (msg.twist.twist.angular.x, msg.twist.twist.angular.y, msg.twist.twist.angular.z)
|
|
279
271
|
)
|
|
280
272
|
|
|
281
|
-
def _lejuclaw_state_callback(self, msg)->None:
|
|
273
|
+
def _lejuclaw_state_callback(self, msg:lejuClawState)->None:
|
|
282
274
|
self._eef_state = (EndEffectorState(
|
|
283
275
|
# left claw
|
|
284
276
|
position = [msg.data.position[0]],
|
|
@@ -293,7 +285,7 @@ class KuavoRobotStateCore:
|
|
|
293
285
|
state=EndEffectorState.GraspingState(msg.state[1])
|
|
294
286
|
))
|
|
295
287
|
|
|
296
|
-
def _dexterous_hand_state_callback(self, msg)->None:
|
|
288
|
+
def _dexterous_hand_state_callback(self, msg:JointState)->None:
|
|
297
289
|
self._eef_state = (EndEffectorState(
|
|
298
290
|
# left hand
|
|
299
291
|
position = list(msg.position[:len(msg.position)//2]),
|
|
@@ -308,7 +300,7 @@ class KuavoRobotStateCore:
|
|
|
308
300
|
state=EndEffectorState.GraspingState.UNKNOWN
|
|
309
301
|
))
|
|
310
302
|
|
|
311
|
-
def _dexhand_touch_state_callback(self, msg)->None:
|
|
303
|
+
def _dexhand_touch_state_callback(self, msg:dexhandTouchState)->None:
|
|
312
304
|
# Update touch state for both hands
|
|
313
305
|
self._dexhand_touch_state = (
|
|
314
306
|
KuavoDexHandTouchState(
|
|
@@ -331,7 +323,7 @@ class KuavoRobotStateCore:
|
|
|
331
323
|
) # Right hand touch state
|
|
332
324
|
)
|
|
333
325
|
|
|
334
|
-
def _humanoid_mpc_gait_changed_callback(self, msg):
|
|
326
|
+
def _humanoid_mpc_gait_changed_callback(self, msg: gaitTimeName):
|
|
335
327
|
"""
|
|
336
328
|
Callback function for gait change messages.
|
|
337
329
|
Updates the current gait name when a gait change occurs.
|
|
@@ -339,7 +331,7 @@ class KuavoRobotStateCore:
|
|
|
339
331
|
SDKLogger.debug(f"[State] Received gait change message: {msg.gait_name} at time {msg.start_time}")
|
|
340
332
|
self._gait_manager.add(msg.start_time, msg.gait_name)
|
|
341
333
|
|
|
342
|
-
def _humanoid_mpc_observation_callback(self, msg) -> None:
|
|
334
|
+
def _humanoid_mpc_observation_callback(self, msg: mpc_observation) -> None:
|
|
343
335
|
"""
|
|
344
336
|
Callback function for MPC observation messages.
|
|
345
337
|
Updates the current MPC state and input data.
|
|
@@ -386,309 +378,3 @@ class KuavoRobotStateCore:
|
|
|
386
378
|
except Exception as e:
|
|
387
379
|
SDKLogger.error(f"Service call failed: {e}")
|
|
388
380
|
return None
|
|
389
|
-
|
|
390
|
-
class KuavoRobotStateCoreWebsocket:
|
|
391
|
-
_instance = None
|
|
392
|
-
|
|
393
|
-
def __new__(cls, *args, **kwargs):
|
|
394
|
-
if not cls._instance:
|
|
395
|
-
cls._instance = super().__new__(cls)
|
|
396
|
-
return cls._instance
|
|
397
|
-
|
|
398
|
-
def __init__(self):
|
|
399
|
-
if not hasattr(self, '_initialized'):
|
|
400
|
-
try:
|
|
401
|
-
self.websocket = WebSocketKuavoSDK()
|
|
402
|
-
if not self.websocket.client.is_connected:
|
|
403
|
-
SDKLogger.error("Failed to connect to WebSocket server")
|
|
404
|
-
raise ConnectionError("Failed to connect to WebSocket server")
|
|
405
|
-
|
|
406
|
-
# Initialize subscribers
|
|
407
|
-
self._sub_sensors_data = roslibpy.Topic(self.websocket.client, '/sensors_data_raw', 'kuavo_msgs/sensorsData')
|
|
408
|
-
self._sub_odom = roslibpy.Topic(self.websocket.client, '/odom', 'nav_msgs/Odometry')
|
|
409
|
-
self._sub_terrain_height = roslibpy.Topic(self.websocket.client, '/humanoid/mpc/terrainHeight', 'std_msgs/Float64')
|
|
410
|
-
self._sub_gait_time_name = roslibpy.Topic(self.websocket.client, '/humanoid_mpc_gait_time_name', 'kuavo_msgs/gaitTimeName')
|
|
411
|
-
self._sub_mpc_observation = roslibpy.Topic(self.websocket.client, '/humanoid_mpc_observation', 'ocs2_msgs/mpc_observation')
|
|
412
|
-
|
|
413
|
-
# service calls are time-consuming after subscription, place them before subscription
|
|
414
|
-
kuavo_info = make_robot_param()
|
|
415
|
-
|
|
416
|
-
# Subscribe to topics
|
|
417
|
-
self._sub_sensors_data.subscribe(self._sensors_data_raw_callback)
|
|
418
|
-
self._sub_odom.subscribe(self._odom_callback)
|
|
419
|
-
self._sub_terrain_height.subscribe(self._terrain_height_callback)
|
|
420
|
-
self._sub_gait_time_name.subscribe(self._humanoid_mpc_gait_changed_callback)
|
|
421
|
-
self._sub_mpc_observation.subscribe(self._humanoid_mpc_observation_callback)
|
|
422
|
-
|
|
423
|
-
if kuavo_info is None:
|
|
424
|
-
SDKLogger.error("Failed to get robot parameters")
|
|
425
|
-
raise RuntimeError("Failed to get robot parameters")
|
|
426
|
-
|
|
427
|
-
self._ee_type = kuavo_info['end_effector_type']
|
|
428
|
-
if self._ee_type == EndEffectorType.LEJUCLAW:
|
|
429
|
-
self._sub_lejuclaw_state = roslibpy.Topic(self.websocket.client, '/leju_claw_state', 'kuavo_msgs/lejuClawState')
|
|
430
|
-
self._sub_lejuclaw_state.subscribe(self._lejuclaw_state_callback)
|
|
431
|
-
elif self._ee_type == EndEffectorType.QIANGNAO:
|
|
432
|
-
self._sub_dexhand_state = roslibpy.Topic(self.websocket.client, '/dexhand/state', 'sensor_msgs/JointState')
|
|
433
|
-
self._sub_dexhand_state.subscribe(self._dexterous_hand_state_callback)
|
|
434
|
-
elif self._ee_type == EndEffectorType.QIANGNAO_TOUCH:
|
|
435
|
-
self._sub_dexhand_state = roslibpy.Topic(self.websocket.client, '/dexhand/state', 'sensor_msgs/JointState')
|
|
436
|
-
self._sub_dexhand_touch_state = roslibpy.Topic(self.websocket.client, '/dexhand/touch_state', 'kuavo_msgs/dexhandTouchState')
|
|
437
|
-
self._sub_dexhand_state.subscribe(self._dexterous_hand_state_callback)
|
|
438
|
-
self._sub_dexhand_touch_state.subscribe(self._dexhand_touch_state_callback)
|
|
439
|
-
# Initialize touch state for both hands
|
|
440
|
-
self._dexhand_touch_state = (
|
|
441
|
-
KuavoDexHandTouchState(
|
|
442
|
-
data=(KuavoDexHandTouchState.KuavoTouchState(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
|
443
|
-
KuavoDexHandTouchState.KuavoTouchState(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
|
444
|
-
KuavoDexHandTouchState.KuavoTouchState(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
|
445
|
-
KuavoDexHandTouchState.KuavoTouchState(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
|
446
|
-
KuavoDexHandTouchState.KuavoTouchState(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
|
|
447
|
-
),
|
|
448
|
-
KuavoDexHandTouchState(
|
|
449
|
-
data=(KuavoDexHandTouchState.KuavoTouchState(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
|
450
|
-
KuavoDexHandTouchState.KuavoTouchState(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
|
451
|
-
KuavoDexHandTouchState.KuavoTouchState(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
|
452
|
-
KuavoDexHandTouchState.KuavoTouchState(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
|
|
453
|
-
KuavoDexHandTouchState.KuavoTouchState(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
|
|
454
|
-
)
|
|
455
|
-
)
|
|
456
|
-
|
|
457
|
-
""" data """
|
|
458
|
-
self._terrain_height = 0.0
|
|
459
|
-
self._imu_data = KuavoImuData(
|
|
460
|
-
gyro = (0.0, 0.0, 0.0),
|
|
461
|
-
acc = (0.0, 0.0, 0.0),
|
|
462
|
-
free_acc = (0.0, 0.0, 0.0),
|
|
463
|
-
quat = (0.0, 0.0, 0.0, 0.0)
|
|
464
|
-
)
|
|
465
|
-
self._joint_data = KuavoJointData(
|
|
466
|
-
position = [0.0] * 28,
|
|
467
|
-
velocity = [0.0] * 28,
|
|
468
|
-
torque = [0.0] * 28,
|
|
469
|
-
acceleration = [0.0] * 28
|
|
470
|
-
)
|
|
471
|
-
self._odom_data = KuavoOdometry(
|
|
472
|
-
position = (0.0, 0.0, 0.0),
|
|
473
|
-
orientation = (0.0, 0.0, 0.0, 0.0),
|
|
474
|
-
linear = (0.0, 0.0, 0.0),
|
|
475
|
-
angular = (0.0, 0.0, 0.0)
|
|
476
|
-
)
|
|
477
|
-
self._eef_state = (EndEffectorState(
|
|
478
|
-
position = [0.0] * 12 if kuavo_info['end_effector_type'].startswith('qiangnao') else [0.0] * 2,
|
|
479
|
-
velocity = [0.0] * 12 if kuavo_info['end_effector_type'].startswith('qiangnao') else [0.0] * 2,
|
|
480
|
-
effort = [0.0] * 12 if kuavo_info['end_effector_type'].startswith('qiangnao') else [0.0] * 2,
|
|
481
|
-
state=EndEffectorState.GraspingState.UNKNOWN
|
|
482
|
-
), EndEffectorState(
|
|
483
|
-
position = [0.0] * 12 if kuavo_info['end_effector_type'].startswith('qiangnao') else [0.0] * 2,
|
|
484
|
-
velocity = [0.0] * 12 if kuavo_info['end_effector_type'].startswith('qiangnao') else [0.0] * 2,
|
|
485
|
-
effort = [0.0] * 12 if kuavo_info['end_effector_type'].startswith('qiangnao') else [0.0] * 2,
|
|
486
|
-
state=EndEffectorState.GraspingState.UNKNOWN
|
|
487
|
-
))
|
|
488
|
-
|
|
489
|
-
# gait manager
|
|
490
|
-
self._gait_manager = GaitManager()
|
|
491
|
-
self._prev_gait_name = self.gait_name
|
|
492
|
-
|
|
493
|
-
# Wait for first MPC observation data
|
|
494
|
-
self._mpc_observation_data = None
|
|
495
|
-
start_time = time.time()
|
|
496
|
-
while self._mpc_observation_data is None:
|
|
497
|
-
if time.time() - start_time > 1.0: # 1.0s timeout
|
|
498
|
-
SDKLogger.warn("Timeout waiting for MPC observation data")
|
|
499
|
-
break
|
|
500
|
-
SDKLogger.debug("Waiting for first MPC observation data...")
|
|
501
|
-
time.sleep(0.1)
|
|
502
|
-
|
|
503
|
-
if self._mpc_observation_data is not None:
|
|
504
|
-
if self._gait_manager.is_empty:
|
|
505
|
-
self._prev_gait_name = self.gait_name()
|
|
506
|
-
SDKLogger.debug(f"[State] Adding initial gait state: {self._prev_gait_name} at time {self._mpc_observation_data['time']}")
|
|
507
|
-
self._gait_manager.add(self._mpc_observation_data['time'], self._prev_gait_name)
|
|
508
|
-
|
|
509
|
-
# 获取当前手臂控制模式
|
|
510
|
-
self._arm_ctrl_mode = self._srv_get_arm_ctrl_mode()
|
|
511
|
-
self._initialized = True
|
|
512
|
-
except Exception as e:
|
|
513
|
-
SDKLogger.error(f"Failed to initialize KuavoRobotStateCoreWebsocket: {e}")
|
|
514
|
-
raise
|
|
515
|
-
|
|
516
|
-
@property
|
|
517
|
-
def com_height(self)->float:
|
|
518
|
-
return self._odom_data.position[2] - self._terrain_height
|
|
519
|
-
|
|
520
|
-
@property
|
|
521
|
-
def imu_data(self)->KuavoImuData:
|
|
522
|
-
return self._imu_data
|
|
523
|
-
|
|
524
|
-
@property
|
|
525
|
-
def joint_data(self)->KuavoJointData:
|
|
526
|
-
return self._joint_data
|
|
527
|
-
|
|
528
|
-
@property
|
|
529
|
-
def odom_data(self)->KuavoOdometry:
|
|
530
|
-
return self._odom_data
|
|
531
|
-
|
|
532
|
-
@property
|
|
533
|
-
def arm_control_mode(self) -> KuavoArmCtrlMode:
|
|
534
|
-
mode = self._srv_get_arm_ctrl_mode()
|
|
535
|
-
if mode is not None:
|
|
536
|
-
self._arm_ctrl_mode = mode
|
|
537
|
-
return self._arm_ctrl_mode
|
|
538
|
-
|
|
539
|
-
@property
|
|
540
|
-
def eef_state(self)->Tuple[EndEffectorState, EndEffectorState]:
|
|
541
|
-
return self._eef_state
|
|
542
|
-
|
|
543
|
-
@property
|
|
544
|
-
def dexhand_touch_state(self)-> Tuple[KuavoDexHandTouchState, KuavoDexHandTouchState]:
|
|
545
|
-
if self._ee_type != EndEffectorType.QIANGNAO_TOUCH:
|
|
546
|
-
raise Exception("This robot does not support touch state")
|
|
547
|
-
return self._dexhand_touch_state
|
|
548
|
-
|
|
549
|
-
@property
|
|
550
|
-
def current_observation_time(self) -> float:
|
|
551
|
-
if self._mpc_observation_data is None:
|
|
552
|
-
return None
|
|
553
|
-
return self._mpc_observation_data.time
|
|
554
|
-
|
|
555
|
-
@property
|
|
556
|
-
def current_gait_mode(self) -> int:
|
|
557
|
-
if self._mpc_observation_data is None:
|
|
558
|
-
return None
|
|
559
|
-
return self._mpc_observation_data.mode
|
|
560
|
-
|
|
561
|
-
def gait_name(self)->str:
|
|
562
|
-
return self._srv_get_current_gait_name()
|
|
563
|
-
|
|
564
|
-
def is_gait(self, gait_name: str) -> bool:
|
|
565
|
-
return self._gait_manager.get_gait(self._mpc_observation_data['time']) == gait_name
|
|
566
|
-
|
|
567
|
-
def register_gait_changed_callback(self, callback):
|
|
568
|
-
if not hasattr(self, '_gait_changed_callbacks'):
|
|
569
|
-
self._gait_changed_callbacks = []
|
|
570
|
-
|
|
571
|
-
from inspect import signature
|
|
572
|
-
sig = signature(callback)
|
|
573
|
-
if len(sig.parameters) != 2:
|
|
574
|
-
raise ValueError("Callback must accept 2 parameters: current_time (float), gait_name (str)")
|
|
575
|
-
if callback not in self._gait_changed_callbacks:
|
|
576
|
-
self._gait_changed_callbacks.append(callback)
|
|
577
|
-
|
|
578
|
-
def _terrain_height_callback(self, msg)->None:
|
|
579
|
-
self._terrain_height = msg['data']
|
|
580
|
-
|
|
581
|
-
def _sensors_data_raw_callback(self, msg)->None:
|
|
582
|
-
# update imu data
|
|
583
|
-
self._imu_data = KuavoImuData(
|
|
584
|
-
gyro = (msg['imu_data']['gyro']['x'], msg['imu_data']['gyro']['y'], msg['imu_data']['gyro']['z']),
|
|
585
|
-
acc = (msg['imu_data']['acc']['x'], msg['imu_data']['acc']['y'], msg['imu_data']['acc']['z']),
|
|
586
|
-
free_acc = (msg['imu_data']['free_acc']['x'], msg['imu_data']['free_acc']['y'], msg['imu_data']['free_acc']['z']),
|
|
587
|
-
quat = (msg['imu_data']['quat']['x'], msg['imu_data']['quat']['y'], msg['imu_data']['quat']['z'], msg['imu_data']['quat']['w'])
|
|
588
|
-
)
|
|
589
|
-
# update joint data
|
|
590
|
-
self._joint_data = KuavoJointData(
|
|
591
|
-
position = copy.deepcopy(msg['joint_data']['joint_q']),
|
|
592
|
-
velocity = copy.deepcopy(msg['joint_data']['joint_v']),
|
|
593
|
-
torque = copy.deepcopy(msg['joint_data']['joint_vd']),
|
|
594
|
-
acceleration = copy.deepcopy(msg['joint_data'].get('joint_current', msg['joint_data']['joint_torque']))
|
|
595
|
-
)
|
|
596
|
-
|
|
597
|
-
def _odom_callback(self, msg)->None:
|
|
598
|
-
# update odom data
|
|
599
|
-
self._odom_data = KuavoOdometry(
|
|
600
|
-
position = (msg['pose']['pose']['position']['x'], msg['pose']['pose']['position']['y'], msg['pose']['pose']['position']['z']),
|
|
601
|
-
orientation = (msg['pose']['pose']['orientation']['x'], msg['pose']['pose']['orientation']['y'], msg['pose']['pose']['orientation']['z'], msg['pose']['pose']['orientation']['w']),
|
|
602
|
-
linear = (msg['twist']['twist']['linear']['x'], msg['twist']['twist']['linear']['y'], msg['twist']['twist']['linear']['z']),
|
|
603
|
-
angular = (msg['twist']['twist']['angular']['x'], msg['twist']['twist']['angular']['y'], msg['twist']['twist']['angular']['z'])
|
|
604
|
-
)
|
|
605
|
-
|
|
606
|
-
def _lejuclaw_state_callback(self, msg)->None:
|
|
607
|
-
self._eef_state = (EndEffectorState(
|
|
608
|
-
position = [msg['data']['position'][0]],
|
|
609
|
-
velocity = [msg['data']['velocity'][0]],
|
|
610
|
-
effort = [msg['data']['effort'][0]],
|
|
611
|
-
state=EndEffectorState.GraspingState(msg['state'][0])
|
|
612
|
-
), EndEffectorState(
|
|
613
|
-
position = [msg['data']['position'][1]],
|
|
614
|
-
velocity = [msg['data']['velocity'][1]],
|
|
615
|
-
effort = [msg['data']['effort'][1]],
|
|
616
|
-
state=EndEffectorState.GraspingState(msg['state'][1])
|
|
617
|
-
))
|
|
618
|
-
|
|
619
|
-
def _dexterous_hand_state_callback(self, msg)->None:
|
|
620
|
-
self._eef_state = (EndEffectorState(
|
|
621
|
-
position = list(msg['position'][:len(msg['position'])//2]),
|
|
622
|
-
velocity = list(msg['velocity'][:len(msg['velocity'])//2]),
|
|
623
|
-
effort = list(msg['effort'][:len(msg['effort'])//2]),
|
|
624
|
-
state=EndEffectorState.GraspingState.UNKNOWN
|
|
625
|
-
), EndEffectorState(
|
|
626
|
-
position = list(msg['position'][len(msg['position'])//2:]),
|
|
627
|
-
velocity = list(msg['velocity'][len(msg['velocity'])//2:]),
|
|
628
|
-
effort = list(msg['effort'][len(msg['effort'])//2:]),
|
|
629
|
-
state=EndEffectorState.GraspingState.UNKNOWN
|
|
630
|
-
))
|
|
631
|
-
|
|
632
|
-
def _dexhand_touch_state_callback(self, msg)->None:
|
|
633
|
-
self._dexhand_touch_state = (
|
|
634
|
-
KuavoDexHandTouchState(
|
|
635
|
-
data=tuple(KuavoDexHandTouchState.KuavoTouchState(
|
|
636
|
-
sensor['normal_force1'], sensor['normal_force2'], sensor['normal_force3'],
|
|
637
|
-
sensor['tangential_force1'], sensor['tangential_force2'], sensor['tangential_force3'],
|
|
638
|
-
sensor['tangential_direction1'], sensor['tangential_direction2'], sensor['tangential_direction3'],
|
|
639
|
-
sensor['self_proximity1'], sensor['self_proximity2'], sensor['mutual_proximity'],
|
|
640
|
-
sensor['status']
|
|
641
|
-
) for sensor in msg['left_hand'])
|
|
642
|
-
),
|
|
643
|
-
KuavoDexHandTouchState(
|
|
644
|
-
data=tuple(KuavoDexHandTouchState.KuavoTouchState(
|
|
645
|
-
sensor['normal_force1'], sensor['normal_force2'], sensor['normal_force3'],
|
|
646
|
-
sensor['tangential_force1'], sensor['tangential_force2'], sensor['tangential_force3'],
|
|
647
|
-
sensor['tangential_direction1'], sensor['tangential_direction2'], sensor['tangential_direction3'],
|
|
648
|
-
sensor['self_proximity1'], sensor['self_proximity2'], sensor['mutual_proximity'],
|
|
649
|
-
sensor['status']
|
|
650
|
-
) for sensor in msg['right_hand'])
|
|
651
|
-
)
|
|
652
|
-
)
|
|
653
|
-
|
|
654
|
-
def _humanoid_mpc_gait_changed_callback(self, msg):
|
|
655
|
-
SDKLogger.debug(f"[State] Received gait change message: {msg['gait_name']} at time {msg['start_time']}")
|
|
656
|
-
self._gait_manager.add(msg['start_time'], msg['gait_name'])
|
|
657
|
-
|
|
658
|
-
def _humanoid_mpc_observation_callback(self, msg) -> None:
|
|
659
|
-
try:
|
|
660
|
-
SDKLogger.debug(f"[State] Received MPC observation message: {msg}")
|
|
661
|
-
self._mpc_observation_data = msg
|
|
662
|
-
if hasattr(self, '_initialized'):
|
|
663
|
-
curr_time = self._mpc_observation_data['time']
|
|
664
|
-
current_gait = self._gait_manager.get_gait(curr_time)
|
|
665
|
-
if self._prev_gait_name != current_gait:
|
|
666
|
-
SDKLogger.debug(f"[State] Gait changed to: {current_gait} at time {curr_time}")
|
|
667
|
-
self._prev_gait_name = current_gait
|
|
668
|
-
if hasattr(self, '_gait_changed_callbacks') and self._gait_changed_callbacks is not None:
|
|
669
|
-
for callback in self._gait_changed_callbacks:
|
|
670
|
-
callback(curr_time, current_gait)
|
|
671
|
-
except Exception as e:
|
|
672
|
-
SDKLogger.error(f"Error processing MPC observation: {e}")
|
|
673
|
-
|
|
674
|
-
def _srv_get_arm_ctrl_mode(self)-> KuavoArmCtrlMode:
|
|
675
|
-
try:
|
|
676
|
-
service = roslibpy.Service(self.websocket.client, '/humanoid_get_arm_ctrl_mode', 'kuavo_msgs/changeArmCtrlMode')
|
|
677
|
-
request = {}
|
|
678
|
-
response = service.call(request)
|
|
679
|
-
return KuavoArmCtrlMode(response.get('mode', 0))
|
|
680
|
-
except Exception as e:
|
|
681
|
-
SDKLogger.error(f"Service call failed: {e}")
|
|
682
|
-
return None
|
|
683
|
-
|
|
684
|
-
def _srv_get_current_gait_name(self)->str:
|
|
685
|
-
try:
|
|
686
|
-
service = roslibpy.Service(self.websocket.client, '/humanoid_get_current_gait_name', 'kuavo_msgs/getCurrentGaitName')
|
|
687
|
-
request = {}
|
|
688
|
-
response = service.call(request)
|
|
689
|
-
if response.get('success', False):
|
|
690
|
-
return response['gait_name']
|
|
691
|
-
return None
|
|
692
|
-
except Exception as e:
|
|
693
|
-
SDKLogger.error(f"Service call failed: {e}")
|
|
694
|
-
return None
|