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.
Files changed (49) hide show
  1. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/PKG-INFO +1 -1
  2. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/__init__.py +1 -0
  3. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/core.py +191 -38
  4. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/ros/control.py +292 -12
  5. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/ros/param.py +129 -40
  6. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/ros_env.py +4 -1
  7. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/robot.py +58 -34
  8. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/robot_arm.py +56 -13
  9. kuavo_humanoid_sdk_ws-1.3.1b4068/kuavo_humanoid_sdk/kuavo/robot_info.py +235 -0
  10. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/robot_state.py +45 -2
  11. kuavo_humanoid_sdk_ws-1.3.1b4068/kuavo_humanoid_sdk/kuavo/robot_waist.py +53 -0
  12. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk_ws.egg-info/PKG-INFO +1 -1
  13. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk_ws.egg-info/SOURCES.txt +1 -0
  14. kuavo_humanoid_sdk_ws-1.3.1b98/kuavo_humanoid_sdk/kuavo/robot_info.py +0 -114
  15. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/README.md +0 -0
  16. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/__init__.py +0 -0
  17. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/common/launch_robot_tool.py +0 -0
  18. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/common/logger.py +0 -0
  19. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/common/websocket_kuavo_sdk.py +0 -0
  20. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/interfaces/__init__.py +0 -0
  21. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/interfaces/data_types.py +0 -0
  22. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/interfaces/end_effector.py +0 -0
  23. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/interfaces/robot.py +0 -0
  24. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/interfaces/robot_info.py +0 -0
  25. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/audio.py +0 -0
  26. {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
  27. {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
  28. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/ros/audio.py +0 -0
  29. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/ros/observation.py +0 -0
  30. {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
  31. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/ros/state.py +0 -0
  32. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/ros/tools.py +0 -0
  33. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/core/ros/vision.py +0 -0
  34. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/dexterous_hand.py +0 -0
  35. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/leju_claw.py +0 -0
  36. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/robot_audio.py +0 -0
  37. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/robot_head.py +0 -0
  38. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/robot_observation.py +0 -0
  39. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/robot_tool.py +0 -0
  40. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo/robot_vision.py +0 -0
  41. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo_strategy/__init__.py +0 -0
  42. {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
  43. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/kuavo_strategy/kuavo_strategy.py +0 -0
  44. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk/msg/__init__.py +0 -0
  45. {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
  46. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/kuavo_humanoid_sdk_ws.egg-info/requires.txt +0 -0
  47. {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
  48. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/setup.cfg +0 -0
  49. {kuavo_humanoid_sdk_ws-1.3.1b98 → kuavo_humanoid_sdk_ws-1.3.1b4068}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: kuavo_humanoid_sdk_ws
3
- Version: 1.3.1b98
3
+ Version: 1.3.1b4068
4
4
  Summary: A Python SDK for kuavo humanoid robot.
5
5
  Home-page: https://gitee.com/leju-robot/kuavo-ros-opensource/
6
6
  Author: ['lejurobot']
@@ -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
- rb_info = make_robot_param()
125
- success, err_msg = self._control.initialize(eef_type=rb_info["end_effector_type"], debug=debug)
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
- # +-0.4, +-0.2, +-0.4 => linear_x, linear_y, angular_z
204
- limited_linear_x = min(0.4, abs(linear_x)) * (1 if linear_x >= 0 else -1)
205
- limited_linear_y = min(0.2, abs(linear_y)) * (1 if linear_y >= 0 else -1)
206
- limited_angular_z = min(0.4, abs(angular_z)) * (1 if angular_z >= 0 else -1)
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
- MIN_HEIGHT = -0.35
215
- MAX_HEIGHT = 0.0
216
- MIN_PITCH = -0.4
217
- MAX_PITCH = 0.4
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.66 # Minimum allowed COM height in meters
257
- MAX_COM_HEIGHT = 0.86 # Maximum allowed COM height in meters
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
- SDKLogger.warn(f"[Core] Cannot squat lower: COM height {com_height:.2f}m below minimum {MIN_COM_HEIGHT}m")
262
- return None
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
- SDKLogger.warn(f"[Core] Cannot stand higher: COM height {com_height:.2f}m above maximum {MAX_COM_HEIGHT}m")
266
- return None
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
- # TODO(kuavo): 根据实物测试来调整....
279
- if com_height > 0.82:
280
- max_x_step = 0.20
281
- max_y_step = 0.20
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
- raise RuntimeError(f"[Core] control_command_pose failed: robot must be in stance state, current state: {self.state}")
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, target_pose_z, target_pose_yaw)
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, target_pose_z, target_pose_yaw)
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
- while self._rb_state.arm_control_mode != mode:
510
- SDKLogger.debug(f"[Core] Change robot arm control from {self._rb_state.arm_control_mode} to {mode}, retry: {count}")
511
- self._control.change_robot_arm_ctrl_mode(mode)
512
- if self._rb_state.arm_control_mode == mode:
513
- break
514
- if timeout <= 0:
515
- SDKLogger.warn("[Core] Change robot arm control mode timeout!")
516
- return False
517
- timeout -= 0.1
518
- time.sleep(0.1)
519
- count += 1
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.debug("[Core] robot manipulation mpc reset, current manipulation mpc ctrl mode != NoControl, change it.")
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.debug("[Core] robot manipulation mpc reset, current manipulation mpc control flow != ThroughFullBodyMpc, change it.")
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