kuavo-humanoid-sdk-ws 1.3.1b98__tar.gz → 1.3.1b4068__tar.gz
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.
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/PKG-INFO +1 -1
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/__init__.py +1 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/core.py +191 -38
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/ros/control.py +292 -12
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/ros/param.py +129 -40
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/ros_env.py +4 -1
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/robot.py +58 -34
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/robot_arm.py +56 -13
- kuavo_humanoid_sdk_ws-1.3.1b4068/kuavo_humanoid_sdk/kuavo/robot_info.py +235 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/robot_state.py +45 -2
- kuavo_humanoid_sdk_ws-1.3.1b4068/kuavo_humanoid_sdk/kuavo/robot_waist.py +53 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk_ws.egg-info/PKG-INFO +1 -1
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk_ws.egg-info/SOURCES.txt +1 -0
- kuavo_humanoid_sdk_ws-1.3.1b98/kuavo_humanoid_sdk/kuavo/robot_info.py +0 -114
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/README.md +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/__init__.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/common/launch_robot_tool.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/common/logger.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/common/websocket_kuavo_sdk.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/interfaces/__init__.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/interfaces/data_types.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/interfaces/end_effector.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/interfaces/robot.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/interfaces/robot_info.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/audio.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/dex_hand_control.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/leju_claw_control.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/ros/audio.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/ros/observation.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/ros/sat_utils.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/ros/state.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/ros/tools.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/ros/vision.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/dexterous_hand.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/leju_claw.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/robot_audio.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/robot_head.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/robot_observation.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/robot_tool.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/robot_vision.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo_strategy/__init__.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo_strategy/grasp_box/grasp_box_strategy.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo_strategy/kuavo_strategy.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/msg/__init__.py +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk_ws.egg-info/dependency_links.txt +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk_ws.egg-info/requires.txt +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk_ws.egg-info/top_level.txt +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/setup.cfg +0 -0
- {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/setup.py +0 -0
|
@@ -5,6 +5,7 @@ from .robot_vision import KuavoRobotVision
|
|
|
5
5
|
from .robot_tool import KuavoRobotTools
|
|
6
6
|
from .robot_arm import KuavoRobotArm
|
|
7
7
|
from .robot_head import KuavoRobotHead
|
|
8
|
+
from .robot_waist import KuavoRobotWaist
|
|
8
9
|
from .robot_audio import KuavoRobotAudio
|
|
9
10
|
from .dexterous_hand import DexterousHand, TouchDexterousHand
|
|
10
11
|
from .leju_claw import LejuClaw
|
|
@@ -121,8 +121,10 @@ class KuavoRobotCore:
|
|
|
121
121
|
raise RuntimeError(f"[Core] initialize failed: \n"
|
|
122
122
|
f"{e}, please check the robot is launched, "
|
|
123
123
|
f"e.g. `roslaunch humanoid_controllers load_kuavo_real.launch`")
|
|
124
|
-
|
|
125
|
-
|
|
124
|
+
self._rb_info = make_robot_param()
|
|
125
|
+
self._robot_version_major = (int(self._rb_info['robot_version']) // 10) % 10000
|
|
126
|
+
success, err_msg = self._control.initialize(eef_type=self._rb_info["end_effector_type"], debug=debug)
|
|
127
|
+
|
|
126
128
|
if not success:
|
|
127
129
|
raise RuntimeError(f"[Core] initialize failed: \n{err_msg}, please check the robot is launched, "
|
|
128
130
|
f"e.g. `roslaunch humanoid_controllers load_kuavo_real.launch`")
|
|
@@ -200,10 +202,21 @@ class KuavoRobotCore:
|
|
|
200
202
|
if self.state != 'walk':
|
|
201
203
|
self.to_walk()
|
|
202
204
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
205
|
+
if self._robot_version_major == 1:
|
|
206
|
+
MAX_LINEAR_X = 0.3
|
|
207
|
+
MAX_LINEAR_Y = 0.2
|
|
208
|
+
MAX_ANGULAR_Z = 0.3
|
|
209
|
+
elif self._robot_version_major == 4 or self._robot_version_major == 5:
|
|
210
|
+
MAX_LINEAR_X = 0.4
|
|
211
|
+
MAX_LINEAR_Y = 0.2
|
|
212
|
+
MAX_ANGULAR_Z = 0.4
|
|
213
|
+
else:
|
|
214
|
+
SDKLogger.warn("[Core] walk failed: robot version is not supported, current version major: {self._robot_version_major}")
|
|
215
|
+
return False
|
|
216
|
+
|
|
217
|
+
limited_linear_x = min(MAX_LINEAR_X, abs(linear_x)) * (1 if linear_x >= 0 else -1)
|
|
218
|
+
limited_linear_y = min(MAX_LINEAR_Y, abs(linear_y)) * (1 if linear_y >= 0 else -1)
|
|
219
|
+
limited_angular_z = min(MAX_ANGULAR_Z, abs(angular_z)) * (1 if angular_z >= 0 else -1)
|
|
207
220
|
return self._control.robot_walk(limited_linear_x, limited_linear_y, limited_angular_z)
|
|
208
221
|
|
|
209
222
|
def squat(self, height:float, pitch:float)->bool:
|
|
@@ -211,10 +224,22 @@ class KuavoRobotCore:
|
|
|
211
224
|
SDKLogger.warn(f"[Core] control torso height failed, robot is not in stance state({self.state})!")
|
|
212
225
|
return False
|
|
213
226
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
227
|
+
if self._robot_version_major == 1:
|
|
228
|
+
MIN_HEIGHT = -0.35
|
|
229
|
+
MAX_HEIGHT = 0.1
|
|
230
|
+
MIN_PITCH = 0
|
|
231
|
+
MAX_PITCH = 0
|
|
232
|
+
if pitch != 0:
|
|
233
|
+
SDKLogger.warn("[Core] roban2 pitch is not supported, will be set to 0")
|
|
234
|
+
pitch = 0
|
|
235
|
+
elif self._robot_version_major == 4 or self._robot_version_major == 5:
|
|
236
|
+
MIN_HEIGHT = -0.35
|
|
237
|
+
MAX_HEIGHT = 0.1
|
|
238
|
+
MIN_PITCH = 0
|
|
239
|
+
MAX_PITCH = 0.4
|
|
240
|
+
else:
|
|
241
|
+
SDKLogger.warn("[Core] control torso height failed: robot version is not supported, current version major: {self._robot_version_major}")
|
|
242
|
+
return False
|
|
218
243
|
|
|
219
244
|
# Limit height range
|
|
220
245
|
limited_height = min(MAX_HEIGHT, max(MIN_HEIGHT, height))
|
|
@@ -226,6 +251,16 @@ class KuavoRobotCore:
|
|
|
226
251
|
if abs(pitch) > MAX_PITCH:
|
|
227
252
|
SDKLogger.warn(f"[Core] pitch {pitch} exceeds limit [{MIN_PITCH}, {MAX_PITCH}], will be limited")
|
|
228
253
|
|
|
254
|
+
# 结合当前高度做过滤
|
|
255
|
+
target_height = self._rb_info['init_stand_height'] + limited_height
|
|
256
|
+
# 躯干上升运动变化不宜过大, 目标高度减去实时躯干高度大于阈值
|
|
257
|
+
HEIGHT_CHANGE_THRESHOLD = 0.25
|
|
258
|
+
if (self._rb_state.com_height < target_height) and (target_height - self._rb_state.com_height) >= HEIGHT_CHANGE_THRESHOLD:
|
|
259
|
+
limited_height = (self._rb_state.com_height + HEIGHT_CHANGE_THRESHOLD)
|
|
260
|
+
print(f"\033[33mWarning! Height change too large, limiting to safe range,reset height to {limited_height}\033[0m")
|
|
261
|
+
else:
|
|
262
|
+
limited_height = target_height
|
|
263
|
+
|
|
229
264
|
return self._control.control_torso_height(limited_height, limited_pitch)
|
|
230
265
|
|
|
231
266
|
def step_control(self, target_pose:list, dt:float=0.4, is_left_first_default:bool=True, collision_check:bool=True)->bool:
|
|
@@ -253,17 +288,23 @@ class KuavoRobotCore:
|
|
|
253
288
|
com_height = self._rb_state.com_height
|
|
254
289
|
# print(f"[Core] Current COM height: {com_height:.2f}m")
|
|
255
290
|
# Check height limits based on current COM height
|
|
256
|
-
MIN_COM_HEIGHT = 0.
|
|
257
|
-
MAX_COM_HEIGHT = 0.
|
|
291
|
+
MIN_COM_HEIGHT = self._rb_info['init_stand_height'] - 0.15 # Minimum allowed COM height in meters
|
|
292
|
+
MAX_COM_HEIGHT = self._rb_info['init_stand_height'] + 0.02 # Maximum allowed COM height in meters
|
|
293
|
+
|
|
294
|
+
if com_height < MIN_COM_HEIGHT:
|
|
295
|
+
print(f"\033[31m[Core] Torso height too low, control failed: current COM height {com_height:.2f}m is below the minimum allowed height {MIN_COM_HEIGHT}m\033[0m")
|
|
296
|
+
return False
|
|
258
297
|
|
|
259
298
|
# Validate COM height constraints
|
|
260
299
|
if target_pose[2] < 0 and com_height < MIN_COM_HEIGHT:
|
|
261
|
-
|
|
262
|
-
return
|
|
300
|
+
print(f"\033[33mWarning! Cannot squat lower: COM height {com_height:.2f}m below minimum {MIN_COM_HEIGHT}m\033[0m")
|
|
301
|
+
return False
|
|
302
|
+
|
|
263
303
|
|
|
264
304
|
if target_pose[2] > 0 and com_height > MAX_COM_HEIGHT:
|
|
265
|
-
|
|
266
|
-
return
|
|
305
|
+
print(f"\033[33mWarning! Cannot stand higher: COM height {com_height:.2f}m above maximum {MAX_COM_HEIGHT}m\033[0m")
|
|
306
|
+
return False
|
|
307
|
+
|
|
267
308
|
|
|
268
309
|
# Ensure target height is within allowed range if height change requested
|
|
269
310
|
if target_pose[2] != 0:
|
|
@@ -275,11 +316,10 @@ class KuavoRobotCore:
|
|
|
275
316
|
SDKLogger.warn(f"[Core] Target height {target_height:.2f}m above maximum {MAX_COM_HEIGHT}m, limiting")
|
|
276
317
|
target_pose[2] = MAX_COM_HEIGHT - com_height
|
|
277
318
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
max_yaw_step = 90
|
|
319
|
+
if com_height > (self._rb_info['init_stand_height']-0.03):
|
|
320
|
+
max_x_step = 0.17
|
|
321
|
+
max_y_step = 0.17
|
|
322
|
+
max_yaw_step = 60
|
|
283
323
|
else:
|
|
284
324
|
max_x_step = 0.15
|
|
285
325
|
max_y_step = 0.15
|
|
@@ -344,13 +384,27 @@ class KuavoRobotCore:
|
|
|
344
384
|
Raises:
|
|
345
385
|
RuntimeError: If robot is not in stance state
|
|
346
386
|
"""
|
|
347
|
-
if self.state != 'stance':
|
|
348
|
-
|
|
387
|
+
# if self.state != 'stance':
|
|
388
|
+
# raise RuntimeError(f"[Core] control_command_pose failed: robot must be in stance state, current state: {self.state}")
|
|
349
389
|
|
|
350
390
|
# Add any parameter validation if needed
|
|
351
391
|
# e.g., limit ranges for safety
|
|
392
|
+
MAX_HEIGHT = 0.1
|
|
393
|
+
MIN_HEIGHT = -0.35
|
|
394
|
+
limited_height = min(MAX_HEIGHT, max(MIN_HEIGHT, target_pose_z))
|
|
395
|
+
if target_pose_z > MAX_HEIGHT or target_pose_z < MIN_HEIGHT:
|
|
396
|
+
SDKLogger.warn(f"[Core] target_pose_z {target_pose_z:.3f} exceeds limit [{MIN_HEIGHT}, {MAX_HEIGHT}], will be limited")
|
|
397
|
+
|
|
398
|
+
# 结合当前高度做过滤,限制上升时的高度变化
|
|
399
|
+
target_height = self._rb_info['init_stand_height'] + limited_height
|
|
400
|
+
# 躯干上升运动变化不宜过大, 目标高度减去实时躯干高度大于阈值
|
|
401
|
+
HEIGHT_CHANGE_THRESHOLD = 0.25
|
|
402
|
+
if (self._rb_state.com_height < target_height) and (target_height - self._rb_state.com_height) >= HEIGHT_CHANGE_THRESHOLD:
|
|
403
|
+
limited_height = (self._rb_state.com_height + HEIGHT_CHANGE_THRESHOLD) - self._rb_info['init_stand_height']
|
|
404
|
+
SDKLogger.warn(f"[Core] Warning! Height change too large, limiting to safe range, reset height to {limited_height:.3f}")
|
|
405
|
+
|
|
352
406
|
self.to_command_pose()
|
|
353
|
-
return self._control.control_command_pose(target_pose_x, target_pose_y,
|
|
407
|
+
return self._control.control_command_pose(target_pose_x, target_pose_y, limited_height, target_pose_yaw)
|
|
354
408
|
|
|
355
409
|
def control_command_pose_world(self, target_pose_x:float, target_pose_y:float, target_pose_z:float, target_pose_yaw:float)->bool:
|
|
356
410
|
"""
|
|
@@ -373,8 +427,23 @@ class KuavoRobotCore:
|
|
|
373
427
|
|
|
374
428
|
# Add any parameter validation if needed
|
|
375
429
|
# e.g., limit ranges for safety
|
|
430
|
+
MAX_HEIGHT = 0.1
|
|
431
|
+
MIN_HEIGHT = -0.35
|
|
432
|
+
# Limit height range
|
|
433
|
+
limited_height = min(MAX_HEIGHT, max(MIN_HEIGHT, target_pose_z))
|
|
434
|
+
if target_pose_z > MAX_HEIGHT or target_pose_z < MIN_HEIGHT:
|
|
435
|
+
SDKLogger.warn(f"[Core] target_pose_z {target_pose_z:.3f} exceeds limit [{MIN_HEIGHT}, {MAX_HEIGHT}], will be limited")
|
|
436
|
+
|
|
437
|
+
# 结合当前高度做过滤,限制上升时的高度变化
|
|
438
|
+
target_height = self._rb_info['init_stand_height'] + limited_height
|
|
439
|
+
# 躯干上升运动变化不宜过大, 目标高度减去实时躯干高度大于阈值
|
|
440
|
+
HEIGHT_CHANGE_THRESHOLD = 0.25
|
|
441
|
+
if (self._rb_state.com_height < target_height) and (target_height - self._rb_state.com_height) >= HEIGHT_CHANGE_THRESHOLD:
|
|
442
|
+
limited_height = (self._rb_state.com_height + HEIGHT_CHANGE_THRESHOLD) - self._rb_info['init_stand_height']
|
|
443
|
+
SDKLogger.warn(f"[Core] Warning! Height change too large, limiting to safe range, reset height to {limited_height:.3f}")
|
|
444
|
+
|
|
376
445
|
self.to_command_pose_world()
|
|
377
|
-
return self._control.control_command_pose_world(target_pose_x, target_pose_y,
|
|
446
|
+
return self._control.control_command_pose_world(target_pose_x, target_pose_y, limited_height, target_pose_yaw)
|
|
378
447
|
|
|
379
448
|
def execute_gesture(self, gestures:list)->bool:
|
|
380
449
|
return self._control.execute_gesture(gestures)
|
|
@@ -398,6 +467,9 @@ class KuavoRobotCore:
|
|
|
398
467
|
pitch_deg = pitch * 180 / math.pi
|
|
399
468
|
return self._control.control_robot_head(yaw_deg, pitch_deg)
|
|
400
469
|
|
|
470
|
+
def control_robot_waist(self, target_pos:list):
|
|
471
|
+
return self._control.control_robot_waist(target_pos)
|
|
472
|
+
|
|
401
473
|
def enable_head_tracking(self, target_id: int)->bool:
|
|
402
474
|
return self._control.enable_head_tracking(target_id)
|
|
403
475
|
|
|
@@ -408,6 +480,9 @@ class KuavoRobotCore:
|
|
|
408
480
|
if self.state != 'stance':
|
|
409
481
|
raise RuntimeError(f"[Core] control_robot_arm_joint_positions failed: robot must be in stance state, current state: {self.state}")
|
|
410
482
|
|
|
483
|
+
if self._control.is_arm_collision_mode() and self._control.is_arm_collision():
|
|
484
|
+
SDKLogger.error(f"Arm collision detected, cannot publish arm trajectory")
|
|
485
|
+
return False
|
|
411
486
|
# change to external control mode
|
|
412
487
|
if self._arm_ctrl_mode != KuavoArmCtrlMode.ExternalControl:
|
|
413
488
|
SDKLogger.debug("[Core] control_robot_arm_joint_positions, current arm mode != ExternalControl, change it.")
|
|
@@ -419,6 +494,10 @@ class KuavoRobotCore:
|
|
|
419
494
|
def control_robot_arm_joint_trajectory(self, times:list, joint_q:list)->bool:
|
|
420
495
|
if self.state != 'stance':
|
|
421
496
|
raise RuntimeError("[Core] control_robot_arm_joint_trajectory failed: robot must be in stance state")
|
|
497
|
+
|
|
498
|
+
if self._control.is_arm_collision_mode() and self._control.is_arm_collision():
|
|
499
|
+
SDKLogger.error(f"Arm collision detected, cannot publish arm trajectory")
|
|
500
|
+
return False
|
|
422
501
|
|
|
423
502
|
if self._arm_ctrl_mode != KuavoArmCtrlMode.ExternalControl:
|
|
424
503
|
SDKLogger.debug("[Core] control_robot_arm_joint_trajectory, current arm mode != ExternalControl, change it.")
|
|
@@ -444,6 +523,16 @@ class KuavoRobotCore:
|
|
|
444
523
|
return self._control.control_robot_end_effector_pose(left_pose, right_pose, frame)
|
|
445
524
|
|
|
446
525
|
def change_manipulation_mpc_frame(self, frame: KuavoManipulationMpcFrame)->bool:
|
|
526
|
+
# Check if service is available (if current state is ERROR, service is not available)
|
|
527
|
+
current_frame = self._rb_state.manipulation_mpc_frame
|
|
528
|
+
if current_frame == KuavoManipulationMpcFrame.ERROR:
|
|
529
|
+
SDKLogger.warn("[Core] Manipulation MPC frame service not available, updating local state only")
|
|
530
|
+
if not hasattr(self, '_manipulation_mpc_frame_lock'):
|
|
531
|
+
self._manipulation_mpc_frame_lock = threading.Lock()
|
|
532
|
+
with self._manipulation_mpc_frame_lock:
|
|
533
|
+
self._manipulation_mpc_frame = frame
|
|
534
|
+
return True
|
|
535
|
+
|
|
447
536
|
timeout = 1.0
|
|
448
537
|
count = 0
|
|
449
538
|
while self._rb_state.manipulation_mpc_frame != frame:
|
|
@@ -464,6 +553,16 @@ class KuavoRobotCore:
|
|
|
464
553
|
return True
|
|
465
554
|
|
|
466
555
|
def change_manipulation_mpc_ctrl_mode(self, control_mode: KuavoManipulationMpcCtrlMode)->bool:
|
|
556
|
+
# Check if service is available (if current state is ERROR, service is not available)
|
|
557
|
+
current_mode = self._rb_state.manipulation_mpc_ctrl_mode
|
|
558
|
+
if current_mode == KuavoManipulationMpcCtrlMode.ERROR:
|
|
559
|
+
SDKLogger.warn("[Core] Manipulation MPC control mode service not available, updating local state only")
|
|
560
|
+
if not hasattr(self, '_manipulation_mpc_ctrl_mode_lock'):
|
|
561
|
+
self._manipulation_mpc_ctrl_mode_lock = threading.Lock()
|
|
562
|
+
with self._manipulation_mpc_ctrl_mode_lock:
|
|
563
|
+
self._manipulation_mpc_ctrl_mode = control_mode
|
|
564
|
+
return True
|
|
565
|
+
|
|
467
566
|
timeout = 1.0
|
|
468
567
|
count = 0
|
|
469
568
|
while self._rb_state.manipulation_mpc_ctrl_mode != control_mode:
|
|
@@ -484,6 +583,16 @@ class KuavoRobotCore:
|
|
|
484
583
|
return True
|
|
485
584
|
|
|
486
585
|
def change_manipulation_mpc_control_flow(self, control_flow: KuavoManipulationMpcControlFlow)->bool:
|
|
586
|
+
# Check if service is available (if current state is ERROR, service is not available)
|
|
587
|
+
current_flow = self._rb_state.manipulation_mpc_control_flow
|
|
588
|
+
if current_flow == KuavoManipulationMpcControlFlow.Error:
|
|
589
|
+
SDKLogger.warn("[Core] Manipulation MPC control flow service not available, updating local state only")
|
|
590
|
+
if not hasattr(self, '_manipulation_mpc_control_flow_lock'):
|
|
591
|
+
self._manipulation_mpc_control_flow_lock = threading.Lock()
|
|
592
|
+
with self._manipulation_mpc_control_flow_lock:
|
|
593
|
+
self._manipulation_mpc_control_flow = control_flow
|
|
594
|
+
return True
|
|
595
|
+
|
|
487
596
|
timeout = 1.0
|
|
488
597
|
count = 0
|
|
489
598
|
while self._rb_state.manipulation_mpc_control_flow != control_flow:
|
|
@@ -504,19 +613,26 @@ class KuavoRobotCore:
|
|
|
504
613
|
return True
|
|
505
614
|
|
|
506
615
|
def change_robot_arm_ctrl_mode(self, mode:KuavoArmCtrlMode)->bool:
|
|
616
|
+
|
|
617
|
+
if self._control.is_arm_collision_mode() and self.is_arm_collision():
|
|
618
|
+
SDKLogger.warn("[Core] change_robot_arm_ctrl_mode failed, arm collision detected!")
|
|
619
|
+
return False
|
|
620
|
+
|
|
621
|
+
# Wait for state update to complete, similar to change_manipulation_mpc_ctrl_mode
|
|
507
622
|
timeout = 1.0
|
|
508
623
|
count = 0
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
624
|
+
if self._rb_state.arm_control_mode != mode:
|
|
625
|
+
while self._rb_state.arm_control_mode != mode:
|
|
626
|
+
SDKLogger.debug(f"[Core] Change robot arm control from {self._rb_state.arm_control_mode} to {mode}, retry: {count}")
|
|
627
|
+
self._control.change_robot_arm_ctrl_mode(mode)
|
|
628
|
+
if self._rb_state.arm_control_mode == mode:
|
|
629
|
+
break
|
|
630
|
+
if timeout <= 0:
|
|
631
|
+
SDKLogger.warn("[Core] Change robot arm control mode timeout!")
|
|
632
|
+
return False
|
|
633
|
+
timeout -= 0.1
|
|
634
|
+
time.sleep(0.1)
|
|
635
|
+
count += 1
|
|
520
636
|
|
|
521
637
|
if not hasattr(self, '_arm_ctrl_mode_lock'):
|
|
522
638
|
self._arm_ctrl_mode_lock = threading.Lock()
|
|
@@ -539,16 +655,27 @@ class KuavoRobotCore:
|
|
|
539
655
|
return self.change_robot_arm_ctrl_mode(KuavoArmCtrlMode.AutoSwing)
|
|
540
656
|
|
|
541
657
|
def robot_manipulation_mpc_reset(self)->bool:
|
|
658
|
+
SDKLogger.info("[Core] Starting manipulation MPC reset...")
|
|
659
|
+
|
|
542
660
|
if self._manipulation_mpc_ctrl_mode != KuavoManipulationMpcCtrlMode.NoControl:
|
|
543
|
-
SDKLogger.
|
|
661
|
+
SDKLogger.info("[Core] Resetting manipulation MPC control mode to NoControl...")
|
|
544
662
|
if not self.change_manipulation_mpc_ctrl_mode(KuavoManipulationMpcCtrlMode.NoControl):
|
|
545
663
|
SDKLogger.warn("[Core] robot manipulation mpc reset failed, change manipulation mpc ctrl mode failed!")
|
|
546
664
|
return False
|
|
665
|
+
SDKLogger.info("[Core] Manipulation MPC control mode reset to NoControl successfully")
|
|
666
|
+
else:
|
|
667
|
+
SDKLogger.info("[Core] Manipulation MPC control mode is already NoControl")
|
|
668
|
+
|
|
547
669
|
if self._manipulation_mpc_control_flow != KuavoManipulationMpcControlFlow.ThroughFullBodyMpc:
|
|
548
|
-
SDKLogger.
|
|
670
|
+
SDKLogger.info("[Core] Resetting manipulation MPC control flow to ThroughFullBodyMpc...")
|
|
549
671
|
if not self.change_manipulation_mpc_control_flow(KuavoManipulationMpcControlFlow.ThroughFullBodyMpc):
|
|
550
672
|
SDKLogger.warn("[Core] robot manipulation mpc reset failed, change manipulation mpc control flow failed!")
|
|
551
673
|
return False
|
|
674
|
+
SDKLogger.info("[Core] Manipulation MPC control flow reset to ThroughFullBodyMpc successfully")
|
|
675
|
+
else:
|
|
676
|
+
SDKLogger.info("[Core] Manipulation MPC control flow is already ThroughFullBodyMpc")
|
|
677
|
+
|
|
678
|
+
SDKLogger.info("[Core] Manipulation MPC reset completed successfully")
|
|
552
679
|
return True
|
|
553
680
|
|
|
554
681
|
""" ------------------------------------------------------------------------"""
|
|
@@ -576,6 +703,32 @@ class KuavoRobotCore:
|
|
|
576
703
|
# Call the transition method if it exists
|
|
577
704
|
getattr(self, to_method)()
|
|
578
705
|
|
|
706
|
+
def is_arm_collision(self)->bool:
|
|
707
|
+
return self._control.is_arm_collision()
|
|
708
|
+
|
|
709
|
+
def is_arm_collision_mode(self)->bool:
|
|
710
|
+
"""Check if arm collision mode is enabled.
|
|
711
|
+
|
|
712
|
+
Returns:
|
|
713
|
+
bool: True if collision mode is enabled, False otherwise.
|
|
714
|
+
"""
|
|
715
|
+
return self._control.is_arm_collision_mode()
|
|
716
|
+
|
|
717
|
+
def release_arm_collision_mode(self):
|
|
718
|
+
|
|
719
|
+
self._control.release_arm_collision_mode()
|
|
720
|
+
# if not self.change_robot_arm_ctrl_mode(KuavoArmCtrlMode.ExternalControl):
|
|
721
|
+
# SDKLogger.warn("[Core] control_robot_arm_joint_positions failed, change robot arm ctrl mode failed!")
|
|
722
|
+
# return False
|
|
723
|
+
|
|
724
|
+
|
|
725
|
+
def wait_arm_collision_complete(self):
|
|
726
|
+
self._control.wait_arm_collision_complete()
|
|
727
|
+
|
|
728
|
+
|
|
729
|
+
def set_arm_collision_mode(self, enable: bool):
|
|
730
|
+
self._control.set_arm_collision_mode(enable)
|
|
731
|
+
|
|
579
732
|
|
|
580
733
|
if __name__ == "__main__":
|
|
581
734
|
DEBUG_MODE = 0
|