kuavo-humanoid-sdk 1.1.5__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.

Files changed (50) hide show
  1. kuavo_humanoid_sdk/__init__.py +0 -2
  2. kuavo_humanoid_sdk/interfaces/data_types.py +0 -90
  3. kuavo_humanoid_sdk/kuavo/__init__.py +0 -3
  4. kuavo_humanoid_sdk/kuavo/core/core.py +20 -238
  5. kuavo_humanoid_sdk/kuavo/core/ros/control.py +27 -1087
  6. kuavo_humanoid_sdk/kuavo/core/ros/param.py +4 -142
  7. kuavo_humanoid_sdk/kuavo/core/ros/state.py +19 -556
  8. kuavo_humanoid_sdk/kuavo/core/ros_env.py +1 -229
  9. kuavo_humanoid_sdk/kuavo/dexterous_hand.py +2 -6
  10. kuavo_humanoid_sdk/kuavo/leju_claw.py +2 -6
  11. kuavo_humanoid_sdk/kuavo/robot.py +27 -150
  12. kuavo_humanoid_sdk/kuavo/robot_arm.py +7 -53
  13. kuavo_humanoid_sdk/kuavo/robot_head.py +0 -10
  14. kuavo_humanoid_sdk/kuavo/robot_info.py +2 -7
  15. kuavo_humanoid_sdk/kuavo/robot_state.py +4 -41
  16. kuavo_humanoid_sdk/msg/kuavo_msgs/msg/__init__.py +0 -7
  17. kuavo_humanoid_sdk/msg/kuavo_msgs/srv/__init__.py +0 -5
  18. kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_playmusic.py +20 -26
  19. kuavo_humanoid_sdk/msg/motion_capture_ik/msg/__init__.py +9 -0
  20. kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/msg/_armHandPose.py +2 -2
  21. kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/msg/_handPose.py +2 -2
  22. kuavo_humanoid_sdk/msg/motion_capture_ik/msg/_headBodyPose.py +145 -0
  23. kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/msg/_ikSolveError.py +13 -13
  24. kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/msg/_ikSolveParam.py +2 -2
  25. kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/msg/_robotArmQVVD.py +2 -2
  26. kuavo_humanoid_sdk/msg/motion_capture_ik/msg/_robotHandPosition.py +225 -0
  27. kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/msg/_twoArmHandPose.py +13 -13
  28. kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/msg/_twoArmHandPoseCmd.py +30 -34
  29. kuavo_humanoid_sdk/msg/motion_capture_ik/srv/__init__.py +4 -0
  30. kuavo_humanoid_sdk/msg/{kuavo_msgs/srv/_setMmCtrlFrame.py → motion_capture_ik/srv/_changeArmCtrlMode.py} +37 -35
  31. kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/srv/_changeArmCtrlModeKuavo.py +5 -5
  32. kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/srv/_fkSrv.py +13 -13
  33. kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/srv/_twoArmHandPoseCmdSrv.py +37 -38
  34. {kuavo_humanoid_sdk-1.1.5.dist-info → kuavo_humanoid_sdk-1.1.6.dist-info}/METADATA +1 -2
  35. {kuavo_humanoid_sdk-1.1.5.dist-info → kuavo_humanoid_sdk-1.1.6.dist-info}/RECORD +37 -46
  36. kuavo_humanoid_sdk/common/global_config.py +0 -16
  37. kuavo_humanoid_sdk/common/websocket_kuavo_sdk.py +0 -23
  38. kuavo_humanoid_sdk/kuavo/core/audio.py +0 -36
  39. kuavo_humanoid_sdk/kuavo/core/ros/audio.py +0 -176
  40. kuavo_humanoid_sdk/kuavo/core/ros/tools.py +0 -158
  41. kuavo_humanoid_sdk/kuavo/core/ros/vision.py +0 -283
  42. kuavo_humanoid_sdk/kuavo/robot_audio.py +0 -39
  43. kuavo_humanoid_sdk/kuavo/robot_tool.py +0 -62
  44. kuavo_humanoid_sdk/kuavo/robot_vision.py +0 -90
  45. kuavo_humanoid_sdk/kuavo_strategy/__init__.py +0 -2
  46. kuavo_humanoid_sdk/kuavo_strategy/grasp_box/grasp_box_strategy.py +0 -418
  47. kuavo_humanoid_sdk/kuavo_strategy/kuavo_strategy.py +0 -63
  48. kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_SpeechSynthesis.py +0 -270
  49. {kuavo_humanoid_sdk-1.1.5.dist-info → kuavo_humanoid_sdk-1.1.6.dist-info}/WHEEL +0 -0
  50. {kuavo_humanoid_sdk-1.1.5.dist-info → kuavo_humanoid_sdk-1.1.6.dist-info}/top_level.txt +0 -0
@@ -1,34 +1,19 @@
1
- from kuavo_humanoid_sdk.common.global_config import GlobalConfig
2
1
  import os
3
- import roslibpy
2
+ import rospy
4
3
  import numpy as np
5
4
  from typing import Tuple
6
5
  from kuavo_humanoid_sdk.common.logger import SDKLogger
7
- from kuavo_humanoid_sdk.common.websocket_kuavo_sdk import WebSocketKuavoSDK
8
- from kuavo_humanoid_sdk.interfaces.data_types import (KuavoArmCtrlMode, KuavoIKParams, KuavoPose,
9
- KuavoManipulationMpcControlFlow, KuavoManipulationMpcCtrlMode
10
- ,KuavoManipulationMpcFrame)
6
+ from kuavo_humanoid_sdk.interfaces.data_types import KuavoArmCtrlMode, KuavoIKParams, KuavoPose
11
7
  from kuavo_humanoid_sdk.kuavo.core.ros.sat_utils import RotatingRectangle
12
8
  from kuavo_humanoid_sdk.kuavo.core.ros.param import EndEffectorType
13
-
14
- try:
15
- import rospy
16
- from geometry_msgs.msg import Twist
17
- from sensor_msgs.msg import JointState, Joy
18
- from kuavo_humanoid_sdk.msg.kuavo_msgs.msg import (gestureTask,robotHandPosition, robotHeadMotionData, armTargetPoses, switchGaitByName,
19
- footPose, footPoseTargetTrajectories, dexhandCommand)
20
- from kuavo_humanoid_sdk.msg.kuavo_msgs.srv import (gestureExecute, gestureExecuteRequest,gestureList, gestureListRequest,
21
- controlLejuClaw, controlLejuClawRequest, changeArmCtrlMode, changeArmCtrlModeRequest,
22
- changeTorsoCtrlMode, changeTorsoCtrlModeRequest, setMmCtrlFrame, setMmCtrlFrameRequest,
23
- setTagId, setTagIdRequest)
24
- from kuavo_humanoid_sdk.msg.kuavo_msgs.msg import twoArmHandPoseCmd, ikSolveParam, armHandPose
25
- from kuavo_humanoid_sdk.msg.kuavo_msgs.srv import twoArmHandPoseCmdSrv, fkSrv
26
- from std_srvs.srv import SetBool, SetBoolRequest
27
- except:
28
- pass
29
-
30
-
31
-
9
+ from geometry_msgs.msg import Twist
10
+ from sensor_msgs.msg import JointState, Joy
11
+ from kuavo_humanoid_sdk.msg.kuavo_msgs.msg import (gestureTask,robotHandPosition, robotHeadMotionData, armTargetPoses, switchGaitByName,
12
+ footPose, footPoseTargetTrajectories, dexhandCommand)
13
+ from kuavo_humanoid_sdk.msg.kuavo_msgs.srv import (gestureExecute, gestureExecuteRequest,gestureList, gestureListRequest,
14
+ controlLejuClaw, controlLejuClawRequest, changeArmCtrlMode, changeArmCtrlModeRequest)
15
+ from kuavo_humanoid_sdk.msg.motion_capture_ik.msg import twoArmHandPoseCmd, ikSolveParam
16
+ from kuavo_humanoid_sdk.msg.motion_capture_ik.srv import twoArmHandPoseCmdSrv, fkSrv
32
17
 
33
18
  class ControlEndEffector:
34
19
  def __init__(self, eef_type: str = EndEffectorType.QIANGNAO):
@@ -190,210 +175,11 @@ class ControlEndEffector:
190
175
  SDKLogger.error(f"Service `control_robot_leju_claw` call failed: {e}")
191
176
  return False
192
177
 
193
- class ControlEndEffectorWebsocket:
194
- def __init__(self, eef_type: str = EndEffectorType.QIANGNAO):
195
- self._eef_type = eef_type
196
- self._pubs = []
197
- websocket = WebSocketKuavoSDK()
198
- if self._eef_type == EndEffectorType.QIANGNAO:
199
- self._pub_ctrl_robot_hand = roslibpy.Topic(websocket.client, '/control_robot_hand_position', 'kuavo_msgs/robotHandPosition')
200
- # publisher, name, require
201
- self._pubs.append((self._pub_ctrl_robot_hand, True))
202
- elif self._eef_type == EndEffectorType.QIANGNAO_TOUCH:
203
- self._pub_ctrl_robot_hand = roslibpy.Topic(websocket.client, '/control_robot_hand_position', 'kuavo_msgs/robotHandPosition')
204
- self._pub_dexhand_command = roslibpy.Topic(websocket.client, '/dexhand/command', 'kuavo_msgs/dexhandCommand')
205
- self._pub_dexhand_right_command = roslibpy.Topic(websocket.client, '/dexhand/right/command', 'kuavo_msgs/dexhandCommand')
206
- self._pub_dexhand_left_command = roslibpy.Topic(websocket.client, '/dexhand/left/command', 'kuavo_msgs/dexhandCommand')
207
- # publisher, name, require
208
- self._pubs.append((self._pub_dexhand_command, True))
209
- self._pubs.append((self._pub_dexhand_right_command, True))
210
- self._pubs.append((self._pub_dexhand_left_command, True))
211
-
212
- def connect(self, timeout:float=1.0)-> bool:
213
- return True
214
-
215
- def pub_control_robot_dexhand(self, left_position:list, right_position:list)->bool:
216
- if not self._eef_type.startswith(EndEffectorType.QIANGNAO): # qiangnao, qiangnao_touch
217
- SDKLogger.warning(f"{self._eef_type} not support control dexhand")
218
- return False
219
- try:
220
- hand_pose_msg = {
221
- "left_hand_position": bytes(left_position),
222
- "right_hand_position": bytes(right_position)
223
- }
224
- self._pub_ctrl_robot_hand.publish(roslibpy.Message(hand_pose_msg))
225
- SDKLogger.debug(f"publish robot dexhand: {left_position}, {right_position}")
226
- return True
227
- except Exception as e:
228
- SDKLogger.error(f"publish robot dexhand: {e}")
229
- return False
230
-
231
- def pub_dexhand_command(self, data:list, ctrl_mode, hand_side)->bool:
232
- """
233
- ctrl_mode: 0 --> POSITION, 1 --> VELOCITY
234
- hand_side: 0 --> left, 1 --> right, 2-->dual
235
- """
236
- if not self._eef_type == EndEffectorType.QIANGNAO_TOUCH:
237
- SDKLogger.warning(f"{self._eef_type} not support pub_left_dexhand_command")
238
- return False
239
- try:
240
- if hand_side != 2 and len(data) != 6:
241
- SDKLogger.warning("Data length should be 6")
242
- return False
243
- if hand_side == 2 and len(data) != 12:
244
- SDKLogger.warning("Data length should be 12")
245
- return False
246
- if ctrl_mode not in [dexhandCommand.POSITION_CONTROL, dexhandCommand.VELOCITY_CONTROL]:
247
- SDKLogger.error(f"Invalid mode for pub_left_dexhand_command: {ctrl_mode}")
248
- return False
249
-
250
- msg = {
251
- "data": [int(d) for d in data], # Convert data to integers
252
- "control_mode": ctrl_mode
253
- }
254
- if hand_side == 0:
255
- self._pub_dexhand_left_command.publish(roslibpy.Message(msg))
256
- elif hand_side == 1:
257
- self._pub_dexhand_right_command.publish(roslibpy.Message(msg))
258
- else:
259
- self._pub_dexhand_command.publish(roslibpy.Message(msg))
260
- return True
261
- except Exception as e:
262
- SDKLogger.error(f"Failed to publish left dexhand command: {e}")
263
- return False
264
-
265
- def srv_execute_gesture(self, gestures:list)->bool:
266
- if not self._eef_type.startswith(EndEffectorType.QIANGNAO): # qiangnao, qiangnao_touch
267
- SDKLogger.warning(f"{self._eef_type} not support control dexhand")
268
- return False
269
- try:
270
- websocket = WebSocketKuavoSDK()
271
- service = roslibpy.Service(websocket.client, 'gesture/execute', 'kuavo_msgs/gestureExecute')
272
- request = {
273
- "gestures": [
274
- {
275
- "gesture_name": gs["gesture_name"],
276
- "hand_side": gs["hand_side"]
277
- } for gs in gestures
278
- ]
279
- }
280
- response = service.call(request)
281
- if not response.get('success', False):
282
- SDKLogger.error(f"Failed to execute gesture '{gestures}': {response.get('message', '')}")
283
- return response.get('success', False)
284
- except Exception as e:
285
- SDKLogger.error(f"Service call failed: {e}")
286
- return False
287
-
288
- def srv_get_gesture_names(self)->list:
289
- if not self._eef_type.startswith(EndEffectorType.QIANGNAO): # qiangnao, qiangnao_touch
290
- SDKLogger.warning(f"{self._eef_type} not support control dexhand")
291
- return []
292
- try:
293
- websocket = WebSocketKuavoSDK()
294
- service = roslibpy.Service(websocket.client, 'gesture/list', 'kuavo_msgs/gestureList')
295
- request = {}
296
- response = service.call(request)
297
- gestures = []
298
- for gesture_info in response.get('gesture_infos', []):
299
- gestures.append(gesture_info['gesture_name'])
300
- for alias in gesture_info.get('alias', []):
301
- gestures.append(alias)
302
- return list(set(gestures))
303
- except Exception as e:
304
- SDKLogger.error(f"Service call failed: {e}")
305
- return []
306
-
307
- def srv_control_leju_claw(self, postions:list, velocities:list, torques:list) ->bool:
308
- if self._eef_type != 'lejuclaw':
309
- SDKLogger.warning(f"{self._eef_type} not support control lejuclaw.")
310
- return False
311
- try:
312
- websocket = WebSocketKuavoSDK()
313
- service = roslibpy.Service(websocket.client, 'control_robot_leju_claw', 'kuavo_msgs/controlLejuClaw')
314
- request = {
315
- "data": {
316
- "position": postions,
317
- "velocity": velocities,
318
- "effort": torques
319
- }
320
- }
321
- response = service.call(request)
322
- if not response.get('result', False):
323
- SDKLogger.error(f"Failed to control leju claw: {response.get('message', '')}")
324
- return response.get('result', False)
325
- except Exception as e:
326
- SDKLogger.error(f"Service `control_robot_leju_claw` call failed: {e}")
327
- return False
328
-
329
- class ControlRobotArmWebsocket:
330
- def __init__(self):
331
- websocket = WebSocketKuavoSDK()
332
- self._pub_ctrl_arm_traj = roslibpy.Topic(websocket.client, '/kuavo_arm_traj', 'sensor_msgs/JointState')
333
- self._pub_ctrl_arm_traj.advertise()
334
- self._pub_ctrl_arm_target_poses = roslibpy.Topic(websocket.client, '/kuavo_arm_target_poses', 'kuavo_msgs/armTargetPoses')
335
- self._pub_ctrl_arm_target_poses.advertise()
336
- def connect(self, timeout:float=1.0)-> bool:
337
- return True
338
-
339
- def pub_control_robot_arm_traj(self, joint_q: list)->bool:
340
- try:
341
- msg = {
342
- "name": ["arm_joint_" + str(i) for i in range(0, 14)],
343
- "position": [float(180.0 / np.pi * q) for q in joint_q] # convert to degree
344
- }
345
- self._pub_ctrl_arm_traj.publish(roslibpy.Message(msg))
346
- return True
347
- except Exception as e:
348
- SDKLogger.error(f"publish robot arm traj: {e}")
349
- return False
350
-
351
- def pub_arm_target_poses(self, times:list, joint_q:list):
352
- try:
353
- msg_values = []
354
- for i in range(len(joint_q)):
355
- degs = [float(q) for q in joint_q[i]]
356
- msg_values.extend(degs)
357
- msg = {
358
- "times": [float(q) for q in times],
359
- "values": msg_values
360
- }
361
- self._pub_ctrl_arm_target_poses.publish(roslibpy.Message(msg))
362
- return True
363
- except Exception as e:
364
- SDKLogger.error(f"publish arm target poses: {e}")
365
-
366
- return False
367
-
368
- def srv_change_arm_ctrl_mode(self, mode: KuavoArmCtrlMode)->bool:
369
- try:
370
- websocket = WebSocketKuavoSDK()
371
- service = roslibpy.Service(websocket.client, '/arm_traj_change_mode', 'kuavo_msgs/changeArmCtrlMode')
372
- request = {
373
- "control_mode": mode.value
374
- }
375
- response = service.call(request)
376
- return response.get('result', False)
377
- except Exception as e:
378
- SDKLogger.error(f"Service call failed: {e}")
379
- return False
380
-
381
- def srv_get_arm_ctrl_mode(self)-> KuavoArmCtrlMode:
382
- try:
383
- websocket = WebSocketKuavoSDK()
384
- service = roslibpy.Service(websocket.client, '/humanoid_get_arm_ctrl_mode', 'kuavo_msgs/changeArmCtrlMode')
385
- request = {}
386
- response = service.call(request)
387
- return KuavoArmCtrlMode(response.get('control_mode', 0))
388
- except Exception as e:
389
- SDKLogger.error(f"Service call failed: {e}")
390
- return None
391
-
178
+ """ Control Robot Arm"""
392
179
  class ControlRobotArm:
393
180
  def __init__(self):
394
181
  self._pub_ctrl_arm_traj = rospy.Publisher('/kuavo_arm_traj', JointState, queue_size=10)
395
182
  self._pub_ctrl_arm_target_poses = rospy.Publisher('/kuavo_arm_target_poses', armTargetPoses, queue_size=10)
396
- self._pub_ctrl_hand_pose_cmd = rospy.Publisher('/mm/two_arm_hand_pose_cmd', twoArmHandPoseCmd, queue_size=10)
397
183
 
398
184
  def connect(self, timeout:float=1.0)-> bool:
399
185
  start_time = rospy.Time.now()
@@ -436,153 +222,6 @@ class ControlRobotArm:
436
222
  except Exception as e:
437
223
  SDKLogger.error(f"publish arm target poses: {e}")
438
224
  return False
439
- def pub_end_effector_pose_cmd(self, left_pose: KuavoPose, right_pose: KuavoPose, frame: KuavoManipulationMpcFrame)->bool:
440
- try:
441
- msg = twoArmHandPoseCmd()
442
- left_pose_msg = armHandPose()
443
- left_pose_msg.pos_xyz = left_pose.position
444
- left_pose_msg.quat_xyzw = left_pose.orientation
445
- right_pose_msg = armHandPose()
446
- right_pose_msg.pos_xyz = right_pose.position
447
- right_pose_msg.quat_xyzw = right_pose.orientation
448
- msg.hand_poses.left_pose = left_pose_msg
449
- msg.hand_poses.right_pose = right_pose_msg
450
- if frame.value not in [0, 1, 2, 3, 4]:
451
- SDKLogger.error(f"Invalid frame: {frame}")
452
- return False
453
- msg.frame = frame.value
454
- self._pub_ctrl_hand_pose_cmd.publish(msg)
455
- return True
456
- except Exception as e:
457
- SDKLogger.error(f"publish arm target poses: {e}")
458
- return False
459
-
460
- def srv_change_manipulation_mpc_frame(self, frame: KuavoManipulationMpcFrame)->bool:
461
- try:
462
- service_name = '/set_mm_ctrl_frame'
463
- rospy.wait_for_service(service_name, timeout=2.0)
464
- set_frame_srv = rospy.ServiceProxy(service_name, setMmCtrlFrame)
465
-
466
- req = setMmCtrlFrameRequest()
467
- req.frame = frame.value
468
-
469
- resp = set_frame_srv(req)
470
- if not resp.result:
471
- SDKLogger.error(f"Failed to change manipulation mpc frame to {frame}: {resp.message}")
472
- return resp.result
473
- except rospy.ServiceException as e:
474
- SDKLogger.error(f"Service call to {service_name} failed: {e}")
475
- except rospy.ROSException as e: # For timeout from wait_for_service
476
- SDKLogger.error(f"Failed to connect to service {service_name}: {e}")
477
- except Exception as e:
478
- SDKLogger.error(f"Failed to change manipulation mpc frame: {e}")
479
- return False
480
-
481
- def srv_change_manipulation_mpc_ctrl_mode(self, ctrl_mode: KuavoManipulationMpcCtrlMode)->bool:
482
- try:
483
- service_name = '/mobile_manipulator_mpc_control'
484
- rospy.wait_for_service(service_name, timeout=2.0)
485
- set_mode_srv = rospy.ServiceProxy(service_name, changeTorsoCtrlMode)
486
-
487
- req = changeTorsoCtrlModeRequest()
488
- req.control_mode = ctrl_mode.value
489
-
490
- resp = set_mode_srv(req)
491
- if not resp.result:
492
- SDKLogger.error(f"Failed to change manipulation mpc control mode to {ctrl_mode}: {resp.message}")
493
- return resp.result
494
- except rospy.ServiceException as e:
495
- SDKLogger.error(f"Service call to {service_name} failed: {e}")
496
- except rospy.ROSException as e: # For timeout from wait_for_service
497
- SDKLogger.error(f"Failed to connect to service {service_name}: {e}")
498
- except Exception as e:
499
- SDKLogger.error(f"Failed to change manipulation mpc control mode: {e}")
500
- return False
501
-
502
- def srv_change_manipulation_mpc_control_flow(self, ctrl_flow: KuavoManipulationMpcControlFlow)-> bool:
503
- try:
504
- service_name = '/enable_mm_wbc_arm_trajectory_control'
505
- rospy.wait_for_service(service_name, timeout=2.0)
506
- set_mode_srv = rospy.ServiceProxy(service_name, changeArmCtrlMode)
507
-
508
- req = changeArmCtrlModeRequest()
509
- req.control_mode = ctrl_flow.value
510
-
511
- resp = set_mode_srv(req)
512
- if not resp.result:
513
- SDKLogger.error(f"Failed to change manipulation mpc wbc arm trajectory control to {ctrl_flow}: {resp.message}")
514
- return resp.result
515
- except rospy.ServiceException as e:
516
- SDKLogger.error(f"Service call to {service_name} failed: {e}")
517
- except rospy.ROSException as e: # For timeout from wait_for_service
518
- SDKLogger.error(f"Failed to connect to service {service_name}: {e}")
519
- except Exception as e:
520
- SDKLogger.error(f"Failed to change manipulation mpc control flow: {e}")
521
- return False
522
-
523
- def srv_get_manipulation_mpc_ctrl_mode(self, )->KuavoManipulationMpcCtrlMode:
524
- try:
525
- service_name = '/mobile_manipulator_get_mpc_control_mode'
526
- rospy.wait_for_service(service_name, timeout=2.0)
527
- get_mode_srv = rospy.ServiceProxy(service_name, changeTorsoCtrlMode)
528
-
529
- req = changeTorsoCtrlModeRequest()
530
-
531
- resp = get_mode_srv(req)
532
- if not resp.result:
533
- SDKLogger.error(f"Failed to get manipulation mpc control mode: {resp.message}")
534
- return KuavoManipulationMpcCtrlMode.ERROR
535
- return KuavoManipulationMpcCtrlMode(resp.mode)
536
- except rospy.ServiceException as e:
537
- SDKLogger.error(f"Service call to {service_name} failed: {e}")
538
- except rospy.ROSException as e: # For timeout from wait_for_service
539
- SDKLogger.error(f"Failed to connect to service {service_name}: {e}")
540
- except Exception as e:
541
- SDKLogger.error(f"Failed to get manipulation mpc control mode: {e}")
542
- return KuavoManipulationMpcCtrlMode.ERROR
543
-
544
- def srv_get_manipulation_mpc_frame(self, )->KuavoManipulationMpcFrame:
545
- try:
546
- service_name = '/get_mm_ctrl_frame'
547
- rospy.wait_for_service(service_name, timeout=2.0)
548
- get_frame_srv = rospy.ServiceProxy(service_name, setMmCtrlFrame)
549
-
550
- req = setMmCtrlFrameRequest()
551
-
552
- resp = get_frame_srv(req)
553
- if not resp.result:
554
- SDKLogger.error(f"Failed to get manipulation mpc frame: {resp.message}")
555
- return KuavoManipulationMpcFrame.ERROR
556
- return KuavoManipulationMpcFrame(resp.currentFrame)
557
- except rospy.ServiceException as e:
558
- SDKLogger.error(f"Service call to {service_name} failed: {e}")
559
- except rospy.ROSException as e: # For timeout from wait_for_service
560
- SDKLogger.error(f"Failed to connect to service {service_name}: {e}")
561
- except Exception as e:
562
- SDKLogger.error(f"Failed to get manipulation mpc frame: {e}")
563
- return KuavoManipulationMpcFrame.ERROR
564
-
565
- def srv_get_manipulation_mpc_control_flow(self, )->KuavoManipulationMpcControlFlow:
566
- try:
567
- service_name = '/get_mm_wbc_arm_trajectory_control'
568
- rospy.wait_for_service(service_name, timeout=2.0)
569
- get_mode_srv = rospy.ServiceProxy(service_name, changeArmCtrlMode)
570
-
571
- req = changeArmCtrlModeRequest()
572
-
573
- resp = get_mode_srv(req)
574
- if not resp.result:
575
- SDKLogger.error(f"Failed to get manipulation mpc wbc arm trajectory control mode: {resp.message}")
576
- return KuavoManipulationMpcControlFlow.ERROR
577
- return KuavoManipulationMpcControlFlow(resp.mode)
578
- except rospy.ServiceException as e:
579
- SDKLogger.error(f"Service call to {service_name} failed: {e}")
580
- except rospy.ROSException as e: # For timeout from wait_for_service
581
- SDKLogger.error(f"Failed to connect to service {service_name}: {e}")
582
- except Exception as e:
583
- SDKLogger.error(f"Failed to get manipulation mpc wbc arm trajectory control mode: {e}")
584
- return KuavoManipulationMpcControlFlow.ERROR
585
-
586
225
 
587
226
  def srv_change_arm_ctrl_mode(self, mode: KuavoArmCtrlMode)->bool:
588
227
  try:
@@ -615,7 +254,7 @@ class ControlRobotArm:
615
254
  class ControlRobotHead:
616
255
  def __init__(self):
617
256
  self._pub_ctrl_robot_head = rospy.Publisher('/robot_head_motion_data', robotHeadMotionData, queue_size=10)
618
-
257
+
619
258
  def connect(self, timeout:float=1.0)->bool:
620
259
  start_time = rospy.Time.now()
621
260
  publishers = [
@@ -638,188 +277,6 @@ class ControlRobotHead:
638
277
  SDKLogger.error(f"[Error] publish robot head: {e}")
639
278
  return False
640
279
 
641
- def srv_enable_head_tracking(self, target_id: int)->bool:
642
- """Enable the head tracking for a specific tag ID.
643
-
644
- Args:
645
- target_id: The ID of the tag to track
646
-
647
- Returns:
648
- bool: True if successful, False otherwise
649
- """
650
- try:
651
- # 首先设置追踪目标ID
652
- service_name = '/set_target_tag_id'
653
- rospy.wait_for_service(service_name, timeout=2.0)
654
- set_tag_id_srv = rospy.ServiceProxy(service_name, setTagId)
655
-
656
- req = setTagIdRequest()
657
- req.tag_id = target_id
658
-
659
- resp = set_tag_id_srv(req)
660
- if not resp.success:
661
- SDKLogger.error(f"Failed to set target tag ID: {resp.message}")
662
- return False
663
-
664
- SDKLogger.info(f"Successfully set target tag ID to {target_id}: {resp.message}")
665
-
666
- # 然后启动连续追踪
667
- service_name = '/continuous_track'
668
- rospy.wait_for_service(service_name, timeout=2.0)
669
- continuous_track_srv = rospy.ServiceProxy(service_name, SetBool)
670
-
671
- req = SetBoolRequest()
672
- req.data = True
673
-
674
- resp = continuous_track_srv(req)
675
- if not resp.success:
676
- SDKLogger.error(f"Failed to start continuous tracking: {resp.message}")
677
- return False
678
-
679
- SDKLogger.info(f"Successfully started continuous tracking: {resp.message}")
680
- return True
681
-
682
- except rospy.ServiceException as e:
683
- SDKLogger.error(f"Service call failed: {e}")
684
- except rospy.ROSException as e:
685
- SDKLogger.error(f"Failed to connect to service: {e}")
686
- except Exception as e:
687
- SDKLogger.error(f"Failed to enable head tracking: {e}")
688
-
689
- return False
690
-
691
- def srv_disable_head_tracking(self)->bool:
692
- """Disable the head tracking.
693
-
694
- Returns:
695
- bool: True if successful, False otherwise
696
- """
697
- try:
698
- service_name = '/continuous_track'
699
- rospy.wait_for_service(service_name, timeout=2.0)
700
- continuous_track_srv = rospy.ServiceProxy(service_name, SetBool)
701
-
702
- req = SetBoolRequest()
703
- req.data = False
704
-
705
- resp = continuous_track_srv(req)
706
- if not resp.success:
707
- SDKLogger.error(f"Failed to stop continuous tracking: {resp.message}")
708
- return False
709
-
710
- SDKLogger.info(f"Successfully stopped continuous tracking: {resp.message}")
711
- return True
712
-
713
- except rospy.ServiceException as e:
714
- SDKLogger.error(f"Service call failed: {e}")
715
- except rospy.ROSException as e:
716
- SDKLogger.error(f"Failed to connect to service: {e}")
717
- except Exception as e:
718
- SDKLogger.error(f"Failed to disable head tracking: {e}")
719
-
720
- return False
721
-
722
- def srv_enable_head_tracking(self, target_id: int)->bool:
723
- """Enable the head tracking for a specific tag ID.
724
-
725
- Args:
726
- target_id: The ID of the tag to track
727
-
728
- Returns:
729
- bool: True if successful, False otherwise
730
- """
731
- try:
732
- # 首先设置追踪目标ID
733
- service_name = '/set_target_tag_id'
734
- rospy.wait_for_service(service_name, timeout=2.0)
735
- set_tag_id_srv = rospy.ServiceProxy(service_name, setTagId)
736
-
737
- req = setTagIdRequest()
738
- req.tag_id = target_id
739
-
740
- resp = set_tag_id_srv(req)
741
- if not resp.success:
742
- SDKLogger.error(f"Failed to set target tag ID: {resp.message}")
743
- return False
744
-
745
- SDKLogger.info(f"Successfully set target tag ID to {target_id}: {resp.message}")
746
-
747
- # 然后启动连续追踪
748
- service_name = '/continuous_track'
749
- rospy.wait_for_service(service_name, timeout=2.0)
750
- continuous_track_srv = rospy.ServiceProxy(service_name, SetBool)
751
-
752
- req = SetBoolRequest()
753
- req.data = True
754
-
755
- resp = continuous_track_srv(req)
756
- if not resp.success:
757
- SDKLogger.error(f"Failed to start continuous tracking: {resp.message}")
758
- return False
759
-
760
- SDKLogger.info(f"Successfully started continuous tracking: {resp.message}")
761
- return True
762
-
763
- except rospy.ServiceException as e:
764
- SDKLogger.error(f"Service call failed: {e}")
765
- except rospy.ROSException as e:
766
- SDKLogger.error(f"Failed to connect to service: {e}")
767
- except Exception as e:
768
- SDKLogger.error(f"Failed to enable head tracking: {e}")
769
-
770
- return False
771
-
772
- def srv_disable_head_tracking(self)->bool:
773
- """Disable the head tracking.
774
-
775
- Returns:
776
- bool: True if successful, False otherwise
777
- """
778
- try:
779
- service_name = '/continuous_track'
780
- rospy.wait_for_service(service_name, timeout=2.0)
781
- continuous_track_srv = rospy.ServiceProxy(service_name, SetBool)
782
-
783
- req = SetBoolRequest()
784
- req.data = False
785
-
786
- resp = continuous_track_srv(req)
787
- if not resp.success:
788
- SDKLogger.error(f"Failed to stop continuous tracking: {resp.message}")
789
- return False
790
-
791
- SDKLogger.info(f"Successfully stopped continuous tracking: {resp.message}")
792
- return True
793
-
794
- except rospy.ServiceException as e:
795
- SDKLogger.error(f"Service call failed: {e}")
796
- except rospy.ROSException as e:
797
- SDKLogger.error(f"Failed to connect to service: {e}")
798
- except Exception as e:
799
- SDKLogger.error(f"Failed to disable head tracking: {e}")
800
-
801
- return False
802
-
803
- """ Control Robot Head """
804
- class ControlRobotHeadWebsocket:
805
- def __init__(self):
806
- websocket = WebSocketKuavoSDK()
807
- self._pub_ctrl_robot_head = roslibpy.Topic(websocket.client, '/robot_head_motion_data', 'kuavo_msgs/robotHeadMotionData')
808
-
809
- def connect(self, timeout:float=1.0)->bool:
810
- return True
811
-
812
- def pub_control_robot_head(self, yaw:float, pitch:float)->bool:
813
- try:
814
- msg = {
815
- "joint_data": [float(yaw), float(pitch)]
816
- }
817
- self._pub_ctrl_robot_head.publish(roslibpy.Message(msg))
818
- return True
819
- except Exception as e:
820
- SDKLogger.error(f"[Error] publish robot head: {e}")
821
- return False
822
-
823
280
  """ Control Robot Motion """
824
281
 
825
282
  # JoyButton constants
@@ -842,12 +299,10 @@ AXIS_RIGHT_RT = 5 # 1 -> (-1)
842
299
  AXIS_LEFT_RIGHT_TRIGGER = 6
843
300
  AXIS_FORWARD_BACK_TRIGGER = 7
844
301
 
845
-
846
302
  class ControlRobotMotion:
847
303
  def __init__(self):
848
304
  self._pub_cmd_vel = rospy.Publisher('/cmd_vel', Twist, queue_size=10)
849
305
  self._pub_cmd_pose = rospy.Publisher('/cmd_pose', Twist, queue_size=10)
850
- self._pub_cmd_pose_world = rospy.Publisher('/cmd_pose_world', Twist, queue_size=10)
851
306
  self._pub_joy = rospy.Publisher('/joy', Joy, queue_size=10)
852
307
  self._pub_switch_gait = rospy.Publisher('/humanoid_switch_gait_by_name', switchGaitByName, queue_size=10)
853
308
  self._pub_step_ctrl = rospy.Publisher('/humanoid_mpc_foot_pose_target_trajectories', footPoseTargetTrajectories, queue_size=10)
@@ -859,8 +314,7 @@ class ControlRobotMotion:
859
314
  (self._pub_cmd_vel, "cmd_vel publisher"),
860
315
  (self._pub_cmd_pose, "cmd_pose publisher"),
861
316
  (self._pub_step_ctrl, "step_ctrl publisher"),
862
- (self._pub_switch_gait, "switch_gait publisher"),
863
- (self._pub_cmd_pose_world, "cmd_pose_world publisher"),
317
+ (self._pub_switch_gait, "switch_gait publisher")
864
318
  ]
865
319
 
866
320
  success = True
@@ -885,22 +339,14 @@ class ControlRobotMotion:
885
339
  SDKLogger.error(f"[Error] publish cmd vel: {e}")
886
340
  return False
887
341
 
888
- def pub_cmd_pose(self, twist)->bool:
342
+ def pub_cmd_pose(self, twist:Twist)->bool:
889
343
  try:
890
344
  self._pub_cmd_pose.publish(twist)
891
345
  return True
892
346
  except Exception as e:
893
347
  SDKLogger.error(f"[Error] publish cmd pose: {e}")
894
348
  return False
895
-
896
- def pub_cmd_pose_world(self, twist:Twist)->bool:
897
- try:
898
- self._pub_cmd_pose_world.publish(twist)
899
- return True
900
- except Exception as e:
901
- SDKLogger.error(f"[Error] publish cmd pose world: {e}")
902
- return False
903
-
349
+
904
350
  def _create_joy_msg(self)->Joy:
905
351
  joy_msg = Joy()
906
352
  joy_msg.axes = [0.0] * 8 # Initialize 8 axes
@@ -947,114 +393,17 @@ class ControlRobotMotion:
947
393
  # return self._pub_joy_command(BUTTON_B, "trot")
948
394
  return self._pub_switch_gait_by_name("walk")
949
395
 
950
- def pub_step_ctrl(self, msg)->bool:
396
+ def pub_step_ctrl(self, msg:footPoseTargetTrajectories)->bool:
951
397
  try:
952
398
  self._pub_step_ctrl.publish(msg)
953
399
  return True
954
400
  except Exception as e:
955
401
  SDKLogger.error(f"[Error] publish step ctrl: {e}")
956
402
  return False
957
-
958
-
959
- class ControlRobotMotionWebsocket:
960
- def __init__(self):
961
- websocket = WebSocketKuavoSDK()
962
- self._pub_cmd_vel = roslibpy.Topic(websocket.client, '/cmd_vel', 'geometry_msgs/Twist')
963
- self._pub_cmd_pose = roslibpy.Topic(websocket.client, '/cmd_pose', 'geometry_msgs/Twist')
964
- self._pub_joy = roslibpy.Topic(websocket.client, '/joy', 'sensor_msgs/Joy')
965
- self._pub_switch_gait = roslibpy.Topic(websocket.client, '/humanoid_switch_gait_by_name', 'kuavo_msgs/switchGaitByName')
966
- self._pub_step_ctrl = roslibpy.Topic(websocket.client, '/humanoid_mpc_foot_pose_target_trajectories', 'kuavo_msgs/footPoseTargetTrajectories')
967
-
968
- def connect(self, timeout:float=2.0)-> bool:
969
- return True
970
-
971
- def pub_cmd_vel(self, linear_x: float, linear_y: float, angular_z: float)->bool:
972
- try:
973
- msg = {
974
- "linear": {"x": float(linear_x), "y": float(linear_y), "z": 0.0},
975
- "angular": {"x": 0.0, "y": 0.0, "z": float(angular_z)}
976
- }
977
- self._pub_cmd_vel.publish(roslibpy.Message(msg))
978
- return True
979
- except Exception as e:
980
- SDKLogger.error(f"[Error] publish cmd vel: {e}")
981
- return False
982
-
983
- def pub_cmd_pose(self, height:float, pitch:float)->bool:
984
- # com_msg = Twist()
985
- # com_msg.linear.z = height
986
- # com_msg.angular.y = pitch
987
- try:
988
- msg = {
989
- "linear": {"x": 0, "y": 0, "z": float(height)},
990
- "angular": {"x": 0, "y": float(pitch), "z": 0}
991
- }
992
- self._pub_cmd_pose.publish(roslibpy.Message(msg))
993
- return True
994
- except Exception as e:
995
- SDKLogger.error(f"[Error] publish cmd pose: {e}")
996
- return False
997
-
998
- def _pub_joy_command(self, button_index: int, command_name: str) -> bool:
999
- try:
1000
- msg = {
1001
- "axes": [0.0] * 8,
1002
- "buttons": [0] * 16
1003
- }
1004
- msg["buttons"][button_index] = 1
1005
- self._pub_joy.publish(roslibpy.Message(msg))
1006
- SDKLogger.debug(f"Published {command_name} command")
1007
- return True
1008
- except Exception as e:
1009
- SDKLogger.error(f"[Error] publish {command_name}: {e}")
1010
- return False
1011
-
1012
- def _pub_switch_gait_by_name(self, gait_name: str) -> bool:
1013
- try:
1014
- msg = {
1015
- "gait_name": gait_name
1016
- }
1017
- self._pub_switch_gait.publish(roslibpy.Message(msg))
1018
- return True
1019
- except Exception as e:
1020
- SDKLogger.error(f"[Error] publish switch gait {gait_name}: {e}")
1021
- return False
1022
-
1023
- def pub_walk_command(self) -> bool:
1024
- return self._pub_switch_gait_by_name("walk")
1025
-
1026
- def pub_stance_command(self) -> bool:
1027
- try:
1028
- self.pub_cmd_vel(linear_x=0.0, linear_y=0.0, angular_z=0.0)
1029
- return self._pub_switch_gait_by_name("stance")
1030
- except Exception as e:
1031
- SDKLogger.error(f"[Error] publish stance: {e}")
1032
- return False
1033
-
1034
- def pub_trot_command(self) -> bool:
1035
- return self._pub_switch_gait_by_name("walk")
1036
-
1037
- def pub_step_ctrl(self, msg)->bool:
1038
- try:
1039
- websocket_msg = {
1040
- "timeTrajectory": msg.timeTrajectory,
1041
- "footIndexTrajectory": msg.footIndexTrajectory,
1042
- "footPoseTrajectory": [
1043
- {
1044
- "footPose": list(fp.footPose),
1045
- "torsoPose": list(fp.torsoPose)
1046
- } for fp in msg.footPoseTrajectory
1047
- ]
1048
- }
1049
- SDKLogger.debug(f"websocket_msg {websocket_msg}")
1050
- self._pub_step_ctrl.publish(roslibpy.Message(websocket_msg))
1051
- SDKLogger.debug(f"after publish")
1052
- return True
1053
- except Exception as e:
1054
- SDKLogger.error(f"[Error] publish step ctrl: {e}")
1055
- return False
1056
-
1057
-
403
+
404
+ """
405
+ Kuavo Robot Arm IK&FK
406
+ """
1058
407
  class KuavoRobotArmIKFK:
1059
408
  def __init__(self):
1060
409
  pass
@@ -1099,7 +448,7 @@ class KuavoRobotArmIKFK:
1099
448
  def arm_fk(self, q: list) -> Tuple[KuavoPose, KuavoPose]:
1100
449
  return self._srv_arm_fk(q)
1101
450
 
1102
- def _srv_arm_ik(self, eef_pose_msg)->list:
451
+ def _srv_arm_ik(self, eef_pose_msg:twoArmHandPoseCmd)->list:
1103
452
  try:
1104
453
  rospy.wait_for_service('/ik/two_arm_hand_pose_cmd_srv',timeout=1.0)
1105
454
  ik_srv = rospy.ServiceProxy('/ik/two_arm_hand_pose_cmd_srv', twoArmHandPoseCmdSrv)
@@ -1131,88 +480,6 @@ class KuavoRobotArmIKFK:
1131
480
  except Exception as e:
1132
481
  print(f"Failed to call ik/fk_srv: {e}")
1133
482
  return None
1134
-
1135
- class KuavoRobotArmIKFKWebsocket:
1136
- def __init__(self):
1137
- pass
1138
-
1139
- def arm_ik(self,
1140
- left_pose: KuavoPose,
1141
- right_pose: KuavoPose,
1142
- left_elbow_pos_xyz: list = [0.0, 0.0, 0.0],
1143
- right_elbow_pos_xyz: list = [0.0, 0.0, 0.0],
1144
- arm_q0: list = None,
1145
- params: KuavoIKParams=None) -> list:
1146
- try:
1147
- websocket = WebSocketKuavoSDK()
1148
- service = roslibpy.Service(websocket.client, '/ik/two_arm_hand_pose_cmd_srv', 'motion_capture_ik/twoArmHandPoseCmdSrv')
1149
-
1150
- request = {
1151
- "twoArmHandPoseCmdRequest": {
1152
- "hand_poses": {
1153
- "header": {
1154
- "seq": 0,
1155
- "stamp": {
1156
- "secs": 0,
1157
- "nsecs": 0
1158
- },
1159
- "frame_id": ""
1160
- },
1161
- "left_pose": {
1162
- "pos_xyz": left_pose.position,
1163
- "quat_xyzw": left_pose.orientation,
1164
- "elbow_pos_xyz": left_elbow_pos_xyz,
1165
- },
1166
- "right_pose": {
1167
- "pos_xyz": right_pose.position,
1168
- "quat_xyzw": right_pose.orientation,
1169
- "elbow_pos_xyz": right_elbow_pos_xyz,
1170
- }
1171
- },
1172
- "use_custom_ik_param": params is not None,
1173
- "joint_angles_as_q0": arm_q0 is not None,
1174
- "ik_param": {
1175
- "major_optimality_tol": params.major_optimality_tol if params else 0.0,
1176
- "major_feasibility_tol": params.major_feasibility_tol if params else 0.0,
1177
- "minor_feasibility_tol": params.minor_feasibility_tol if params else 0.0,
1178
- "major_iterations_limit": params.major_iterations_limit if params else 0,
1179
- "oritation_constraint_tol": params.oritation_constraint_tol if params else 0.0,
1180
- "pos_constraint_tol": params.pos_constraint_tol if params else 0.0,
1181
- "pos_cost_weight": params.pos_cost_weight if params else 0.0
1182
- }
1183
- }
1184
- }
1185
-
1186
- response = service.call(request)
1187
- if response.get('success', False):
1188
- return response['hand_poses']['left_pose']['joint_angles'] + response['hand_poses']['right_pose']['joint_angles']
1189
- return None
1190
- except Exception as e:
1191
- SDKLogger.error(f"Service call failed: {e}")
1192
- return None
1193
-
1194
- def arm_fk(self, q: list) -> Tuple[KuavoPose, KuavoPose]:
1195
- try:
1196
- websocket = WebSocketKuavoSDK()
1197
- service = roslibpy.Service(websocket.client, '/ik/fk_srv', 'motion_capture_ik/fkSrv')
1198
- request = {"q": q}
1199
- response = service.call(request)
1200
-
1201
- if response.get('success', False):
1202
- left_pose = KuavoPose(
1203
- position=response['hand_poses']['left_pose']['pos_xyz'],
1204
- orientation=response['hand_poses']['left_pose']['quat_xyzw']
1205
- )
1206
- right_pose = KuavoPose(
1207
- position=response['hand_poses']['right_pose']['pos_xyz'],
1208
- orientation=response['hand_poses']['right_pose']['quat_xyzw']
1209
- )
1210
- return left_pose, right_pose
1211
- return None
1212
- except Exception as e:
1213
- SDKLogger.error(f"Service call failed: {e}")
1214
- return None
1215
-
1216
483
  """
1217
484
  Kuavo Robot Control
1218
485
  """
@@ -1346,39 +613,19 @@ class KuavoRobotControl:
1346
613
  SDKLogger.debug(f"Control robot head: {yaw}, {pitch}")
1347
614
  return self.kuavo_head_control.pub_control_robot_head(yaw, pitch)
1348
615
 
1349
- def enable_head_tracking(self, target_id: int)->bool:
1350
- """Enable the head tracking for a specific tag ID.
1351
-
1352
- Args:
1353
- target_id: The ID of the tag to track
1354
-
1355
- Returns:
1356
- bool: True if successful, False otherwise
1357
- """
1358
- SDKLogger.debug(f"Enable head tracking: {target_id}")
1359
- return self.kuavo_head_control.srv_enable_head_tracking(target_id)
1360
-
1361
- def disable_head_tracking(self)->bool:
1362
- """Disable the head tracking.
1363
-
1364
- Returns:
1365
- bool: True if successful, False otherwise
1366
- """
1367
- SDKLogger.debug(f"Disable head tracking")
1368
- return self.kuavo_head_control.srv_disable_head_tracking()
1369
-
1370
- def control_robot_arm_joint_positions(self, joint_data:list)->bool:
616
+
617
+ def control_robot_arm_traj(self, joint_data:list)->bool:
1371
618
  """
1372
- Control robot arm joint positions
619
+ Control robot arm trajectory
1373
620
  Arguments:
1374
621
  - joint_data: list of joint data (degrees)
1375
622
  """
1376
623
  # SDKLogger.debug(f"[ROS] Control robot arm trajectory: {joint_data}")
1377
624
  return self.kuavo_arm_control.pub_control_robot_arm_traj(joint_data)
1378
625
 
1379
- def control_robot_arm_joint_trajectory(self, times:list, joint_q:list)->bool:
626
+ def control_robot_arm_target_poses(self, times:list, joint_q:list)->bool:
1380
627
  """
1381
- Control robot arm joint trajectory
628
+ Control robot arm target poses
1382
629
  Arguments:
1383
630
  - times: list of times (seconds)
1384
631
  - joint_q: list of joint data (degrees)
@@ -1390,58 +637,6 @@ class KuavoRobotControl:
1390
637
 
1391
638
  return self.kuavo_arm_control.pub_arm_target_poses(times=times, joint_q=joint_q)
1392
639
 
1393
- def control_robot_end_effector_pose(self, left_pose: KuavoPose, right_pose: KuavoPose, frame: KuavoManipulationMpcFrame)->bool:
1394
- """
1395
- Control robot end effector pose
1396
- Arguments:
1397
- - left_pose: left end effector pose
1398
- - right_pose: right end effector pose
1399
- - frame: frame of the end effector pose, 0: keep current frame, 1: world frame, 2: local frame, 3: VR frame, 4: manipulation world frame
1400
- """
1401
- return self.kuavo_arm_control.pub_end_effector_pose_cmd(left_pose, right_pose, frame)
1402
-
1403
- def change_manipulation_mpc_frame(self, frame: KuavoManipulationMpcFrame)->bool:
1404
- """
1405
- Change manipulation mpc frame
1406
- Arguments:
1407
- - frame: frame of the manipulation mpc
1408
- """
1409
- return self.kuavo_arm_control.srv_change_manipulation_mpc_frame(frame)
1410
-
1411
- def change_manipulation_mpc_ctrl_mode(self, ctrl_mode: KuavoManipulationMpcCtrlMode)->bool:
1412
- """
1413
- Change manipulation mpc control mode
1414
- Arguments:
1415
- - control_mode: control mode of the manipulation mpc
1416
- """
1417
- return self.kuavo_arm_control.srv_change_manipulation_mpc_ctrl_mode(ctrl_mode)
1418
-
1419
- def change_manipulation_mpc_control_flow(self, ctrl_flow: KuavoManipulationMpcControlFlow)->bool:
1420
- """
1421
- Change manipulation mpc wbc arm traj control mode, control signal will be sent to wbc directly
1422
- Arguments:
1423
- - control_mode: control mode of the manipulation mpc wbc arm traj
1424
- """
1425
- return self.kuavo_arm_control.srv_change_manipulation_mpc_control_flow(ctrl_flow)
1426
-
1427
- def get_manipulation_mpc_ctrl_mode(self)->KuavoManipulationMpcCtrlMode:
1428
- """
1429
- Get manipulation mpc control mode
1430
- """
1431
- return self.kuavo_arm_control.srv_get_manipulation_mpc_ctrl_mode()
1432
-
1433
- def get_manipulation_mpc_frame(self)-> KuavoManipulationMpcFrame:
1434
- """
1435
- Get manipulation mpc frame
1436
- """
1437
- return self.kuavo_arm_control.srv_get_manipulation_mpc_frame()
1438
-
1439
- def get_manipulation_mpc_control_flow(self)->KuavoManipulationMpcControlFlow:
1440
- """
1441
- Get manipulation mpc wbc arm traj control mode
1442
- """
1443
- return self.kuavo_arm_control.srv_get_manipulation_mpc_control_flow()
1444
-
1445
640
  def change_robot_arm_ctrl_mode(self, mode:KuavoArmCtrlMode)->bool:
1446
641
  """
1447
642
  Change robot arm control mode
@@ -1483,28 +678,6 @@ class KuavoRobotControl:
1483
678
  com_msg.angular.y = pitch
1484
679
  return self.kuavo_motion_control.pub_cmd_pose(com_msg)
1485
680
 
1486
- def control_command_pose_world(self, target_pose_x:float, target_pose_y:float, target_pose_z:float, target_pose_yaw:float)->bool:
1487
- """
1488
- odom下的机器人cmd_pose_world
1489
- """
1490
- com_msg = Twist()
1491
- com_msg.linear.x = target_pose_x
1492
- com_msg.linear.y = target_pose_y
1493
- com_msg.linear.z = target_pose_z
1494
- com_msg.angular.z = target_pose_yaw
1495
- return self.kuavo_motion_control.pub_cmd_pose_world(com_msg)
1496
-
1497
- def control_command_pose(self, target_pose_x:float, target_pose_y:float, target_pose_z:float, target_pose_yaw:float)->bool:
1498
- """
1499
- base_link下的机器人cmd_pose
1500
- """
1501
- com_msg = Twist()
1502
- com_msg.linear.x = target_pose_x
1503
- com_msg.linear.y = target_pose_y
1504
- com_msg.linear.z = target_pose_z
1505
- com_msg.angular.z = target_pose_yaw
1506
- return self.kuavo_motion_control.pub_cmd_pose(com_msg)
1507
-
1508
681
  def step_control(self, body_poses:list, dt:float, is_left_first_default:bool=True, collision_check:bool=True)->bool:
1509
682
  """
1510
683
  Step control
@@ -1525,226 +698,6 @@ class KuavoRobotControl:
1525
698
  msg = get_multiple_steps_msg(body_poses, dt, is_left_first_default, collision_check)
1526
699
  return self.kuavo_motion_control.pub_step_ctrl(msg)
1527
700
  """ ------------------------------------------------------------------------------"""
1528
-
1529
-
1530
- class KuavoRobotControlWebsocket:
1531
- _instance = None
1532
-
1533
- def __new__(cls, *args, **kwargs):
1534
- if not cls._instance:
1535
- cls._instance = super().__new__(cls)
1536
- return cls._instance
1537
-
1538
- def __init__(self):
1539
- if not hasattr(self, '_initialized'):
1540
- try:
1541
- self._initialized = True
1542
- self.kuavo_eef_control = None
1543
- self.kuavo_head_control = ControlRobotHeadWebsocket()
1544
- self.kuavo_arm_control = ControlRobotArmWebsocket()
1545
- self.kuavo_motion_control = ControlRobotMotionWebsocket()
1546
- self.kuavo_arm_ik_fk = KuavoRobotArmIKFKWebsocket()
1547
- except Exception as e:
1548
- SDKLogger.error(f"Failed to initialize KuavoRobotControlWebsocket: {e}")
1549
- raise
1550
-
1551
- def initialize(self, eef_type:str=None, debug:bool=False, timeout:float=1.0)-> Tuple[bool, str]:
1552
- try:
1553
- # init eef control
1554
- if eef_type is None:
1555
- self.kuavo_eef_control = None
1556
- else:
1557
- self.kuavo_eef_control = ControlEndEffectorWebsocket(eef_type=eef_type)
1558
-
1559
- connect_success = True
1560
- err_msg = ''
1561
- if not self.kuavo_arm_control.connect(timeout):
1562
- connect_success = False
1563
- err_msg = "Failed to connect to arm control topics, \n"
1564
- if not self.kuavo_head_control.connect(timeout):
1565
- connect_success = False
1566
- err_msg += "Failed to connect to head control topics, \n"
1567
- if not self.kuavo_motion_control.connect(timeout):
1568
- err_msg += "Failed to connect to motion control topics, \n"
1569
- connect_success = False
1570
-
1571
- if self.kuavo_eef_control is not None and not self.kuavo_eef_control.connect(timeout):
1572
- connect_success = False
1573
- err_msg += "Failed to connect to end effector control topics."
1574
-
1575
- if connect_success:
1576
- err_msg = 'success'
1577
- return connect_success, err_msg
1578
- except Exception as e:
1579
- SDKLogger.error(f"Failed to initialize KuavoRobotControlWebsocket: {e}")
1580
- return False, str(e)
1581
-
1582
- """ End Effector Control"""
1583
- def control_robot_dexhand(self, left_position:list, right_position:list)->bool:
1584
- """
1585
- Control robot dexhand
1586
- Args:
1587
- left_position: list of 6 floats between 0 and 100
1588
- right_position: list of 6 floats between 0 and 100
1589
- """
1590
- if self.kuavo_eef_control is None:
1591
- SDKLogger.error("End effector control is not initialized.")
1592
- return False
1593
-
1594
- if len(left_position) != 6 or len(right_position) != 6:
1595
- raise ValueError("Position lists must have a length of 6.")
1596
-
1597
- for position in left_position + right_position:
1598
- if position < 0.0 or position > 100.0:
1599
- raise ValueError("All position values must be in the range [0.0, 100.0].")
1600
-
1601
- SDKLogger.debug(f"Control robot dexhand: {left_position}, {right_position}")
1602
- return self.kuavo_eef_control.pub_control_robot_dexhand(left_position, right_position)
1603
-
1604
- def robot_dexhand_command(self, data, ctrl_mode, hand_side):
1605
- """
1606
- Publish dexhand command
1607
- Args:
1608
- - data: list of 6 floats between 0 and 100
1609
- - ctrl_mode: int between 0(position), 1(velocity)
1610
- - hand_side: int between 0(left), 1(right), 2(dual)
1611
- """
1612
- if self.kuavo_eef_control is None:
1613
- SDKLogger.error("End effector control is not initialized.")
1614
- return False
1615
- return self.kuavo_eef_control.pub_dexhand_command(data, ctrl_mode, hand_side)
1616
-
1617
- def execute_gesture(self, gestures:list)->bool:
1618
- """
1619
- Execute gestures
1620
- Arguments:
1621
- - gestures: list of dicts with keys 'gesture_name' and 'hand_side'
1622
- e.g. [{'gesture_name': 'fist', 'hand_side': 0},]
1623
- """
1624
- if self.kuavo_eef_control is None:
1625
- SDKLogger.warn("End effectors control is not initialized.")
1626
- return False
1627
- return self.kuavo_eef_control.srv_execute_gesture(gestures)
1628
-
1629
- def get_gesture_names(self)->list:
1630
- """
1631
- Get the names of all gestures.
1632
- """
1633
- if self.kuavo_eef_control is None:
1634
- SDKLogger.warn("End effectors control is not initialized.")
1635
- return []
1636
- return self.kuavo_eef_control.srv_get_gesture_names()
1637
-
1638
- def control_leju_claw(self, postions:list, velocities:list=[90, 90], torques:list=[1.0, 1.0]) ->bool:
1639
- """
1640
- Control leju claw
1641
- Arguments:
1642
- - postions: list of positions for left and right claw
1643
- - velocities: list of velocities for left and right claw
1644
- - torques: list of torques for left and right claw
1645
- """
1646
- if self.kuavo_eef_control is None:
1647
- SDKLogger.warn("End effectors control is not initialized.")
1648
- return False
1649
- SDKLogger.debug(f"Control leju claw: {postions}, {velocities}, {torques}")
1650
- if len(postions) != 2 or len(velocities) != 2 or len(torques) != 2:
1651
- raise ValueError("Position, velocity, and torque lists must have a length of 2.")
1652
- return self.kuavo_eef_control.srv_control_leju_claw(postions, velocities, torques)
1653
-
1654
- def control_robot_head(self, yaw:float, pitch:float)->bool:
1655
- """
1656
- Control robot head
1657
- Arguments:
1658
- - yaw: yaw angle, radian
1659
- - pitch: pitch angle, radian
1660
- """
1661
- SDKLogger.debug(f"Control robot head: {yaw}, {pitch}")
1662
- return self.kuavo_head_control.pub_control_robot_head(yaw, pitch)
1663
-
1664
- def control_robot_arm_traj(self, joint_data:list)->bool:
1665
- """
1666
- Control robot arm trajectory
1667
- Arguments:
1668
- - joint_data: list of joint data (degrees)
1669
- """
1670
- return self.kuavo_arm_control.pub_control_robot_arm_traj(joint_data)
1671
-
1672
- def control_robot_arm_target_poses(self, times:list, joint_q:list)->bool:
1673
- """
1674
- Control robot arm target poses
1675
- Arguments:
1676
- - times: list of times (seconds)
1677
- - joint_q: list of joint data (degrees)
1678
- """
1679
- if len(times) != len(joint_q):
1680
- raise ValueError("Times and joint_q must have the same length.")
1681
- elif len(times) == 0:
1682
- raise ValueError("Times and joint_q must not be empty.")
1683
-
1684
- return self.kuavo_arm_control.pub_arm_target_poses(times=times, joint_q=joint_q)
1685
-
1686
- def change_robot_arm_ctrl_mode(self, mode:KuavoArmCtrlMode)->bool:
1687
- """
1688
- Change robot arm control mode
1689
- Arguments:
1690
- - mode: arm control mode
1691
- """
1692
- SDKLogger.debug(f"[WebSocket] Change robot arm control mode: {mode}")
1693
- return self.kuavo_arm_control.srv_change_arm_ctrl_mode(mode)
1694
-
1695
- def get_robot_arm_ctrl_mode(self)->int:
1696
- """
1697
- Get robot arm control mode
1698
- """
1699
- return self.kuavo_arm_control.srv_get_arm_ctrl_mode()
1700
-
1701
- def arm_ik(self, left_pose: KuavoPose, right_pose: KuavoPose,
1702
- left_elbow_pos_xyz: list = [0.0, 0.0, 0.0],
1703
- right_elbow_pos_xyz: list = [0.0, 0.0, 0.0],
1704
- arm_q0: list = None, params: KuavoIKParams=None) -> list:
1705
- return self.kuavo_arm_ik_fk.arm_ik(left_pose, right_pose, left_elbow_pos_xyz, right_elbow_pos_xyz, arm_q0, params)
1706
-
1707
- def arm_fk(self, q: list) -> Tuple[KuavoPose, KuavoPose]:
1708
- return self.kuavo_arm_ik_fk.arm_fk(q)
1709
-
1710
- """ Motion """
1711
- def robot_stance(self)->bool:
1712
- return self.kuavo_motion_control.pub_stance_command()
1713
-
1714
- def robot_trot(self)->bool:
1715
- return self.kuavo_motion_control.pub_trot_command()
1716
-
1717
- def robot_walk(self, linear_x:float, linear_y:float, angular_z:float)->bool:
1718
- return self.kuavo_motion_control.pub_cmd_vel(linear_x, linear_y, angular_z)
1719
-
1720
- def control_torso_height(self, height:float, pitch:float=0.0)->bool:
1721
- return self.kuavo_motion_control.pub_cmd_pose(height, pitch)
1722
-
1723
- def step_control(self, body_poses:list, dt:float, is_left_first_default:bool=True, collision_check:bool=True)->bool:
1724
- """
1725
- Step control
1726
- Arguments:
1727
- - body_poses: list of body poses (x, y, z, yaw), meters and degrees
1728
- - dt: time step (seconds)
1729
- - is_left_first_default: whether to start with left foot
1730
- - collision_check: whether to check for collisions
1731
- """
1732
- if len(body_poses) == 0:
1733
- raise ValueError("Body poses must not be empty.")
1734
- if dt <= 0.0:
1735
- raise ValueError("Time step must be greater than 0.0.")
1736
- for bp in body_poses:
1737
- if len(bp) != 4:
1738
- raise ValueError("Body pose must have 4 elements: [x, y, z, yaw]")
1739
-
1740
- msg = get_multiple_steps_msg(body_poses, dt, is_left_first_default, collision_check)
1741
- return self.kuavo_motion_control.pub_step_ctrl(msg)
1742
-
1743
- # if GlobalConfig.use_websocket:
1744
- # kuavo_robot_control = KuavoRobotControlWebsocket()
1745
- # else:
1746
- # kuavo_robot_control = KuavoRobotControl()
1747
-
1748
701
  def euler_to_rotation_matrix(yaw, pitch, roll):
1749
702
  # 计算各轴的旋转矩阵
1750
703
  R_yaw = np.array([[np.cos(yaw), -np.sin(yaw), 0],
@@ -1858,17 +811,4 @@ def get_multiple_steps_msg(body_poses:list, dt:float, is_left_first:bool=True, c
1858
811
  # print("foot_traj:", foot_traj)
1859
812
  # print("torso_traj:", torso_traj)
1860
813
  return get_foot_pose_traj_msg(time_traj, foot_idx_traj, foot_traj, torso_traj)
1861
- """ ------------------------------------------------------------------------------"""
1862
-
1863
-
1864
- # if __name__ == "__main__":
1865
- # control = KuavoRobotControl()
1866
- # control.change_manipulation_mpc_frame(KuavoManipulationMpcFrame.KeepCurrentFrame)
1867
- # control.change_manipulation_mpc_ctrl_mode(KuavoManipulationMpcCtrlMode.ArmOnly)
1868
- # control.change_manipulation_mpc_control_flow(KuavoManipulationMpcControlFlow.DirectToWbc)
1869
- # print(control.get_manipulation_mpc_ctrl_mode())
1870
- # print(control.get_manipulation_mpc_frame())
1871
- # print(control.get_manipulation_mpc_control_flow())
1872
- # control.change_manipulation_mpc_frame(KuavoManipulationMpcFrame.WorldFrame)
1873
- # control.change_robot_arm_ctrl_mode(KuavoArmCtrlMode.ExternalControl)
1874
- # control.control_robot_end_effector_pose(KuavoPose(position=[0.3, 0.4, 0.9], orientation=[0.0, 0.0, 0.0, 1.0]), KuavoPose(position=[0.3, -0.5, 1.0], orientation=[0.0, 0.0, 0.0, 1.0]), KuavoManipulationMpcFrame.WorldFrame)
814
+ """ ------------------------------------------------------------------------------"""