kuavo-humanoid-sdk 1.1.3a1240__py3-none-any.whl → 1.1.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of kuavo-humanoid-sdk might be problematic. Click here for more details.
- kuavo_humanoid_sdk/__init__.py +2 -0
- kuavo_humanoid_sdk/common/global_config.py +1 -0
- kuavo_humanoid_sdk/interfaces/data_types.py +44 -0
- kuavo_humanoid_sdk/kuavo/core/audio.py +6 -2
- kuavo_humanoid_sdk/kuavo/core/core.py +225 -18
- kuavo_humanoid_sdk/kuavo/core/ros/audio.py +86 -3
- kuavo_humanoid_sdk/kuavo/core/ros/control.py +447 -13
- kuavo_humanoid_sdk/kuavo/core/ros/state.py +228 -5
- kuavo_humanoid_sdk/kuavo/core/ros/vision.py +13 -6
- kuavo_humanoid_sdk/kuavo/robot.py +108 -6
- kuavo_humanoid_sdk/kuavo/robot_arm.py +53 -7
- kuavo_humanoid_sdk/kuavo/robot_head.py +10 -0
- kuavo_humanoid_sdk/kuavo/robot_state.py +35 -2
- kuavo_humanoid_sdk/kuavo_strategy/__init__.py +2 -0
- kuavo_humanoid_sdk/kuavo_strategy/grasp_box/grasp_box_strategy.py +418 -0
- kuavo_humanoid_sdk/kuavo_strategy/kuavo_strategy.py +63 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/_twoArmHandPoseCmd.py +20 -16
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/__init__.py +1 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_setMmCtrlFrame.py +273 -0
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_twoArmHandPoseCmdSrv.py +15 -14
- {kuavo_humanoid_sdk-1.1.3a1240.dist-info → kuavo_humanoid_sdk-1.1.5.dist-info}/METADATA +1 -1
- {kuavo_humanoid_sdk-1.1.3a1240.dist-info → kuavo_humanoid_sdk-1.1.5.dist-info}/RECORD +24 -20
- {kuavo_humanoid_sdk-1.1.3a1240.dist-info → kuavo_humanoid_sdk-1.1.5.dist-info}/WHEEL +0 -0
- {kuavo_humanoid_sdk-1.1.3a1240.dist-info → kuavo_humanoid_sdk-1.1.5.dist-info}/top_level.txt +0 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import roslibpy
|
|
2
|
-
import copy
|
|
3
2
|
import time
|
|
4
3
|
from typing import Tuple
|
|
5
4
|
|
|
@@ -14,12 +13,14 @@ try:
|
|
|
14
13
|
except:
|
|
15
14
|
pass
|
|
16
15
|
|
|
17
|
-
from kuavo_humanoid_sdk.interfaces.data_types import (KuavoImuData, KuavoJointData, KuavoOdometry,
|
|
18
|
-
KuavoArmCtrlMode, EndEffectorState, KuavoDexHandTouchState
|
|
16
|
+
from kuavo_humanoid_sdk.interfaces.data_types import (KuavoImuData, KuavoJointData, KuavoOdometry, KuavoManipulationMpcFrame,
|
|
17
|
+
KuavoArmCtrlMode, EndEffectorState, KuavoDexHandTouchState,
|
|
18
|
+
KuavoManipulationMpcCtrlMode, KuavoManipulationMpcControlFlow)
|
|
19
19
|
from kuavo_humanoid_sdk.kuavo.core.ros.param import make_robot_param, EndEffectorType
|
|
20
20
|
from kuavo_humanoid_sdk.common.logger import SDKLogger
|
|
21
21
|
from kuavo_humanoid_sdk.common.websocket_kuavo_sdk import WebSocketKuavoSDK
|
|
22
|
-
|
|
22
|
+
from kuavo_humanoid_sdk.msg.kuavo_msgs.srv import (changeArmCtrlMode, changeArmCtrlModeRequest,setMmCtrlFrame, setMmCtrlFrameRequest,
|
|
23
|
+
changeTorsoCtrlMode, changeTorsoCtrlModeRequest)
|
|
23
24
|
from collections import deque
|
|
24
25
|
from typing import Tuple, Optional
|
|
25
26
|
|
|
@@ -157,6 +158,11 @@ class KuavoRobotStateCore:
|
|
|
157
158
|
self._arm_ctrl_mode = self._srv_get_arm_ctrl_mode()
|
|
158
159
|
self._initialized = True
|
|
159
160
|
|
|
161
|
+
# 获取manipulation mpc 相关参数
|
|
162
|
+
self._manipulation_mpc_frame = self._srv_get_manipulation_mpc_frame()
|
|
163
|
+
self._manipulation_mpc_ctrl_mode = self._srv_get_manipulation_mpc_ctrl_mode()
|
|
164
|
+
self._manipulation_mpc_control_flow = self._srv_get_manipulation_mpc_control_flow()
|
|
165
|
+
|
|
160
166
|
@property
|
|
161
167
|
def com_height(self)->float:
|
|
162
168
|
# odom.position.z - terrain_height = com_height
|
|
@@ -181,6 +187,27 @@ class KuavoRobotStateCore:
|
|
|
181
187
|
self._arm_ctrl_mode = mode
|
|
182
188
|
return self._arm_ctrl_mode
|
|
183
189
|
|
|
190
|
+
@property
|
|
191
|
+
def manipulation_mpc_ctrl_mode(self)->KuavoManipulationMpcCtrlMode:
|
|
192
|
+
mode = self._srv_get_manipulation_mpc_ctrl_mode()
|
|
193
|
+
if mode is not None:
|
|
194
|
+
self._manipulation_mpc_ctrl_mode = mode
|
|
195
|
+
return self._manipulation_mpc_ctrl_mode
|
|
196
|
+
|
|
197
|
+
@property
|
|
198
|
+
def manipulation_mpc_frame(self)->KuavoManipulationMpcFrame:
|
|
199
|
+
frame = self._srv_get_manipulation_mpc_frame()
|
|
200
|
+
if frame is not None:
|
|
201
|
+
self._manipulation_mpc_frame = frame
|
|
202
|
+
return self._manipulation_mpc_frame
|
|
203
|
+
|
|
204
|
+
@property
|
|
205
|
+
def manipulation_mpc_control_flow(self)->KuavoManipulationMpcControlFlow:
|
|
206
|
+
flow = self._srv_get_manipulation_mpc_control_flow()
|
|
207
|
+
if flow is not None:
|
|
208
|
+
self._manipulation_mpc_control_flow = flow
|
|
209
|
+
return self._manipulation_mpc_control_flow
|
|
210
|
+
|
|
184
211
|
@property
|
|
185
212
|
def eef_state(self)->Tuple[EndEffectorState, EndEffectorState]:
|
|
186
213
|
return self._eef_state
|
|
@@ -387,6 +414,194 @@ class KuavoRobotStateCore:
|
|
|
387
414
|
SDKLogger.error(f"Service call failed: {e}")
|
|
388
415
|
return None
|
|
389
416
|
|
|
417
|
+
def _srv_get_manipulation_mpc_ctrl_mode(self, )->KuavoManipulationMpcCtrlMode:
|
|
418
|
+
try:
|
|
419
|
+
service_name = '/mobile_manipulator_get_mpc_control_mode'
|
|
420
|
+
rospy.wait_for_service(service_name, timeout=2.0)
|
|
421
|
+
get_mode_srv = rospy.ServiceProxy(service_name, changeTorsoCtrlMode)
|
|
422
|
+
|
|
423
|
+
req = changeTorsoCtrlModeRequest()
|
|
424
|
+
|
|
425
|
+
resp = get_mode_srv(req)
|
|
426
|
+
if not resp.result:
|
|
427
|
+
SDKLogger.error(f"Failed to get manipulation mpc control mode: {resp.message}")
|
|
428
|
+
return KuavoManipulationMpcCtrlMode.ERROR
|
|
429
|
+
return KuavoManipulationMpcCtrlMode(resp.mode)
|
|
430
|
+
except rospy.ServiceException as e:
|
|
431
|
+
SDKLogger.error(f"Service call to {service_name} failed: {e}")
|
|
432
|
+
except rospy.ROSException as e: # For timeout from wait_for_service
|
|
433
|
+
SDKLogger.error(f"Failed to connect to service {service_name}: {e}")
|
|
434
|
+
except Exception as e:
|
|
435
|
+
SDKLogger.error(f"Failed to get manipulation mpc control mode: {e}")
|
|
436
|
+
return KuavoManipulationMpcCtrlMode.ERROR
|
|
437
|
+
|
|
438
|
+
def _srv_get_manipulation_mpc_frame(self, )->KuavoManipulationMpcFrame:
|
|
439
|
+
try:
|
|
440
|
+
service_name = '/get_mm_ctrl_frame'
|
|
441
|
+
rospy.wait_for_service(service_name, timeout=2.0)
|
|
442
|
+
get_frame_srv = rospy.ServiceProxy(service_name, setMmCtrlFrame)
|
|
443
|
+
|
|
444
|
+
req = setMmCtrlFrameRequest()
|
|
445
|
+
|
|
446
|
+
resp = get_frame_srv(req)
|
|
447
|
+
if not resp.result:
|
|
448
|
+
SDKLogger.error(f"Failed to get manipulation mpc frame: {resp.message}")
|
|
449
|
+
return KuavoManipulationMpcFrame.ERROR
|
|
450
|
+
return KuavoManipulationMpcFrame(resp.currentFrame)
|
|
451
|
+
except rospy.ServiceException as e:
|
|
452
|
+
SDKLogger.error(f"Service call to {service_name} failed: {e}")
|
|
453
|
+
except rospy.ROSException as e: # For timeout from wait_for_service
|
|
454
|
+
SDKLogger.error(f"Failed to connect to service {service_name}: {e}")
|
|
455
|
+
except Exception as e:
|
|
456
|
+
SDKLogger.error(f"Failed to get manipulation mpc frame: {e}")
|
|
457
|
+
return KuavoManipulationMpcFrame.ERROR
|
|
458
|
+
|
|
459
|
+
def _srv_get_manipulation_mpc_control_flow(self, )->KuavoManipulationMpcControlFlow:
|
|
460
|
+
try:
|
|
461
|
+
service_name = '/get_mm_wbc_arm_trajectory_control'
|
|
462
|
+
rospy.wait_for_service(service_name, timeout=2.0)
|
|
463
|
+
get_mode_srv = rospy.ServiceProxy(service_name, changeArmCtrlMode)
|
|
464
|
+
|
|
465
|
+
req = changeArmCtrlModeRequest()
|
|
466
|
+
|
|
467
|
+
resp = get_mode_srv(req)
|
|
468
|
+
if not resp.result:
|
|
469
|
+
SDKLogger.error(f"Failed to get manipulation mpc wbc arm trajectory control mode: {resp.message}")
|
|
470
|
+
return KuavoManipulationMpcControlFlow.Error
|
|
471
|
+
return KuavoManipulationMpcControlFlow(resp.mode)
|
|
472
|
+
except rospy.ServiceException as e:
|
|
473
|
+
SDKLogger.error(f"Service call to {service_name} failed: {e}")
|
|
474
|
+
except rospy.ROSException as e: # For timeout from wait_for_service
|
|
475
|
+
SDKLogger.error(f"Failed to connect to service {service_name}: {e}")
|
|
476
|
+
except Exception as e:
|
|
477
|
+
SDKLogger.error(f"Failed to get manipulation mpc wbc arm trajectory control mode: {e}")
|
|
478
|
+
return KuavoManipulationMpcControlFlow.Error
|
|
479
|
+
|
|
480
|
+
def _srv_get_manipulation_mpc_ctrl_mode(self, )->KuavoManipulationMpcCtrlMode:
|
|
481
|
+
try:
|
|
482
|
+
service_name = '/mobile_manipulator_get_mpc_control_mode'
|
|
483
|
+
rospy.wait_for_service(service_name, timeout=2.0)
|
|
484
|
+
get_mode_srv = rospy.ServiceProxy(service_name, changeTorsoCtrlMode)
|
|
485
|
+
|
|
486
|
+
req = changeTorsoCtrlModeRequest()
|
|
487
|
+
|
|
488
|
+
resp = get_mode_srv(req)
|
|
489
|
+
if not resp.result:
|
|
490
|
+
SDKLogger.error(f"Failed to get manipulation mpc control mode: {resp.message}")
|
|
491
|
+
return KuavoManipulationMpcCtrlMode.ERROR
|
|
492
|
+
return KuavoManipulationMpcCtrlMode(resp.mode)
|
|
493
|
+
except rospy.ServiceException as e:
|
|
494
|
+
SDKLogger.error(f"Service call to {service_name} failed: {e}")
|
|
495
|
+
except rospy.ROSException as e: # For timeout from wait_for_service
|
|
496
|
+
SDKLogger.error(f"Failed to connect to service {service_name}: {e}")
|
|
497
|
+
except Exception as e:
|
|
498
|
+
SDKLogger.error(f"Failed to get manipulation mpc control mode: {e}")
|
|
499
|
+
return KuavoManipulationMpcCtrlMode.ERROR
|
|
500
|
+
|
|
501
|
+
def _srv_get_manipulation_mpc_frame(self, )->KuavoManipulationMpcFrame:
|
|
502
|
+
try:
|
|
503
|
+
service_name = '/get_mm_ctrl_frame'
|
|
504
|
+
rospy.wait_for_service(service_name, timeout=2.0)
|
|
505
|
+
get_frame_srv = rospy.ServiceProxy(service_name, setMmCtrlFrame)
|
|
506
|
+
|
|
507
|
+
req = setMmCtrlFrameRequest()
|
|
508
|
+
|
|
509
|
+
resp = get_frame_srv(req)
|
|
510
|
+
if not resp.result:
|
|
511
|
+
SDKLogger.error(f"Failed to get manipulation mpc frame: {resp.message}")
|
|
512
|
+
return KuavoManipulationMpcFrame.ERROR
|
|
513
|
+
return KuavoManipulationMpcFrame(resp.currentFrame)
|
|
514
|
+
except rospy.ServiceException as e:
|
|
515
|
+
SDKLogger.error(f"Service call to {service_name} failed: {e}")
|
|
516
|
+
except rospy.ROSException as e: # For timeout from wait_for_service
|
|
517
|
+
SDKLogger.error(f"Failed to connect to service {service_name}: {e}")
|
|
518
|
+
except Exception as e:
|
|
519
|
+
SDKLogger.error(f"Failed to get manipulation mpc frame: {e}")
|
|
520
|
+
return KuavoManipulationMpcFrame.ERROR
|
|
521
|
+
|
|
522
|
+
def _srv_get_manipulation_mpc_control_flow(self, )->KuavoManipulationMpcControlFlow:
|
|
523
|
+
try:
|
|
524
|
+
service_name = '/get_mm_wbc_arm_trajectory_control'
|
|
525
|
+
rospy.wait_for_service(service_name, timeout=2.0)
|
|
526
|
+
get_mode_srv = rospy.ServiceProxy(service_name, changeArmCtrlMode)
|
|
527
|
+
|
|
528
|
+
req = changeArmCtrlModeRequest()
|
|
529
|
+
|
|
530
|
+
resp = get_mode_srv(req)
|
|
531
|
+
if not resp.result:
|
|
532
|
+
SDKLogger.error(f"Failed to get manipulation mpc wbc arm trajectory control mode: {resp.message}")
|
|
533
|
+
return KuavoManipulationMpcControlFlow.Error
|
|
534
|
+
return KuavoManipulationMpcControlFlow(resp.mode)
|
|
535
|
+
except rospy.ServiceException as e:
|
|
536
|
+
SDKLogger.error(f"Service call to {service_name} failed: {e}")
|
|
537
|
+
except rospy.ROSException as e: # For timeout from wait_for_service
|
|
538
|
+
SDKLogger.error(f"Failed to connect to service {service_name}: {e}")
|
|
539
|
+
except Exception as e:
|
|
540
|
+
SDKLogger.error(f"Failed to get manipulation mpc wbc arm trajectory control mode: {e}")
|
|
541
|
+
return KuavoManipulationMpcControlFlow.Error
|
|
542
|
+
|
|
543
|
+
def _srv_get_manipulation_mpc_ctrl_mode(self, )->KuavoManipulationMpcCtrlMode:
|
|
544
|
+
try:
|
|
545
|
+
service_name = '/mobile_manipulator_get_mpc_control_mode'
|
|
546
|
+
rospy.wait_for_service(service_name, timeout=2.0)
|
|
547
|
+
get_mode_srv = rospy.ServiceProxy(service_name, changeTorsoCtrlMode)
|
|
548
|
+
|
|
549
|
+
req = changeTorsoCtrlModeRequest()
|
|
550
|
+
|
|
551
|
+
resp = get_mode_srv(req)
|
|
552
|
+
if not resp.result:
|
|
553
|
+
SDKLogger.error(f"Failed to get manipulation mpc control mode: {resp.message}")
|
|
554
|
+
return KuavoManipulationMpcCtrlMode.ERROR
|
|
555
|
+
return KuavoManipulationMpcCtrlMode(resp.mode)
|
|
556
|
+
except rospy.ServiceException as e:
|
|
557
|
+
SDKLogger.error(f"Service call to {service_name} failed: {e}")
|
|
558
|
+
except rospy.ROSException as e: # For timeout from wait_for_service
|
|
559
|
+
SDKLogger.error(f"Failed to connect to service {service_name}: {e}")
|
|
560
|
+
except Exception as e:
|
|
561
|
+
SDKLogger.error(f"Failed to get manipulation mpc control mode: {e}")
|
|
562
|
+
return KuavoManipulationMpcCtrlMode.ERROR
|
|
563
|
+
|
|
564
|
+
def _srv_get_manipulation_mpc_frame(self, )->KuavoManipulationMpcFrame:
|
|
565
|
+
try:
|
|
566
|
+
service_name = '/get_mm_ctrl_frame'
|
|
567
|
+
rospy.wait_for_service(service_name, timeout=2.0)
|
|
568
|
+
get_frame_srv = rospy.ServiceProxy(service_name, setMmCtrlFrame)
|
|
569
|
+
|
|
570
|
+
req = setMmCtrlFrameRequest()
|
|
571
|
+
|
|
572
|
+
resp = get_frame_srv(req)
|
|
573
|
+
if not resp.result:
|
|
574
|
+
SDKLogger.error(f"Failed to get manipulation mpc frame: {resp.message}")
|
|
575
|
+
return KuavoManipulationMpcFrame.ERROR
|
|
576
|
+
return KuavoManipulationMpcFrame(resp.currentFrame)
|
|
577
|
+
except rospy.ServiceException as e:
|
|
578
|
+
SDKLogger.error(f"Service call to {service_name} failed: {e}")
|
|
579
|
+
except rospy.ROSException as e: # For timeout from wait_for_service
|
|
580
|
+
SDKLogger.error(f"Failed to connect to service {service_name}: {e}")
|
|
581
|
+
except Exception as e:
|
|
582
|
+
SDKLogger.error(f"Failed to get manipulation mpc frame: {e}")
|
|
583
|
+
return KuavoManipulationMpcFrame.ERROR
|
|
584
|
+
|
|
585
|
+
def _srv_get_manipulation_mpc_control_flow(self, )->KuavoManipulationMpcControlFlow:
|
|
586
|
+
try:
|
|
587
|
+
service_name = '/get_mm_wbc_arm_trajectory_control'
|
|
588
|
+
rospy.wait_for_service(service_name, timeout=2.0)
|
|
589
|
+
get_mode_srv = rospy.ServiceProxy(service_name, changeArmCtrlMode)
|
|
590
|
+
|
|
591
|
+
req = changeArmCtrlModeRequest()
|
|
592
|
+
|
|
593
|
+
resp = get_mode_srv(req)
|
|
594
|
+
if not resp.result:
|
|
595
|
+
SDKLogger.error(f"Failed to get manipulation mpc wbc arm trajectory control mode: {resp.message}")
|
|
596
|
+
return KuavoManipulationMpcControlFlow.Error
|
|
597
|
+
return KuavoManipulationMpcControlFlow(resp.mode)
|
|
598
|
+
except rospy.ServiceException as e:
|
|
599
|
+
SDKLogger.error(f"Service call to {service_name} failed: {e}")
|
|
600
|
+
except rospy.ROSException as e: # For timeout from wait_for_service
|
|
601
|
+
SDKLogger.error(f"Failed to connect to service {service_name}: {e}")
|
|
602
|
+
except Exception as e:
|
|
603
|
+
SDKLogger.error(f"Failed to get manipulation mpc wbc arm trajectory control mode: {e}")
|
|
604
|
+
return KuavoManipulationMpcControlFlow.Error
|
|
390
605
|
class KuavoRobotStateCoreWebsocket:
|
|
391
606
|
_instance = None
|
|
392
607
|
|
|
@@ -691,4 +906,12 @@ class KuavoRobotStateCoreWebsocket:
|
|
|
691
906
|
return None
|
|
692
907
|
except Exception as e:
|
|
693
908
|
SDKLogger.error(f"Service call failed: {e}")
|
|
694
|
-
return None
|
|
909
|
+
return None
|
|
910
|
+
|
|
911
|
+
|
|
912
|
+
if __name__ == "__main__":
|
|
913
|
+
state = KuavoRobotStateCore()
|
|
914
|
+
print(state.manipulation_mpc_frame)
|
|
915
|
+
print(state.manipulation_mpc_control_flow)
|
|
916
|
+
print(state.manipulation_mpc_ctrl_mode)
|
|
917
|
+
print(state.arm_control_mode)
|
|
@@ -34,16 +34,16 @@ class KuavoRobotVisionCore:
|
|
|
34
34
|
def __init__(self):
|
|
35
35
|
"""Initializes vision system components including TF and AprilTag subscribers."""
|
|
36
36
|
if not hasattr(self, '_initialized'):
|
|
37
|
+
# Initialize TF components
|
|
37
38
|
self.tf_buffer = tf2_ros.Buffer()
|
|
38
39
|
self.tf_listener = tf2_ros.TransformListener(self.tf_buffer)
|
|
39
40
|
self.tf_broadcaster = tf2_ros.TransformBroadcaster()
|
|
40
|
-
|
|
41
|
-
self._apriltag_data_base_sub = rospy.Subscriber('/robot_tag_info', AprilTagDetectionArray, self._apriltag_data_callback_base)
|
|
42
|
-
|
|
41
|
+
|
|
43
42
|
# 添加TF2监听器
|
|
44
43
|
self._tf_buffer = tf2_ros.Buffer()
|
|
45
44
|
self._tf_listener = tf2_ros.TransformListener(self._tf_buffer)
|
|
46
45
|
|
|
46
|
+
# FIRST: Initialize data structures before creating subscribers
|
|
47
47
|
""" data """
|
|
48
48
|
self._apriltag_data_from_camera = AprilTagData(
|
|
49
49
|
id = [],
|
|
@@ -62,6 +62,13 @@ class KuavoRobotVisionCore:
|
|
|
62
62
|
size = [],
|
|
63
63
|
pose = []
|
|
64
64
|
)
|
|
65
|
+
|
|
66
|
+
# THEN: Create subscribers after all data structures are initialized
|
|
67
|
+
self._apriltag_data_camera_sub = rospy.Subscriber('/tag_detections', AprilTagDetectionArray, self._apriltag_data_callback_camera)
|
|
68
|
+
self._apriltag_data_base_sub = rospy.Subscriber('/robot_tag_info', AprilTagDetectionArray, self._apriltag_data_callback_base)
|
|
69
|
+
|
|
70
|
+
# Mark as initialized
|
|
71
|
+
self._initialized = True
|
|
65
72
|
|
|
66
73
|
def _apriltag_data_callback_camera(self, data):
|
|
67
74
|
"""Callback for processing AprilTag detections from camera.
|
|
@@ -147,7 +154,7 @@ class KuavoRobotVisionCore:
|
|
|
147
154
|
|
|
148
155
|
# 如果base数据为空,则不处理
|
|
149
156
|
if not self._apriltag_data_from_base.id:
|
|
150
|
-
SDKLogger.warn("No base tag data, skip transform")
|
|
157
|
+
# SDKLogger.warn("No base tag data, skip transform")
|
|
151
158
|
return
|
|
152
159
|
|
|
153
160
|
try:
|
|
@@ -246,7 +253,7 @@ class KuavoRobotVisionCore:
|
|
|
246
253
|
}
|
|
247
254
|
|
|
248
255
|
if data_source not in data_map:
|
|
249
|
-
SDKLogger.error(f"Invalid data source: {data_source}, must be one of {list(data_map.keys())}")
|
|
256
|
+
# SDKLogger.error(f"Invalid data source: {data_source}, must be one of {list(data_map.keys())}")
|
|
250
257
|
return None
|
|
251
258
|
|
|
252
259
|
data = data_map[data_source]
|
|
@@ -255,7 +262,7 @@ class KuavoRobotVisionCore:
|
|
|
255
262
|
indices = [i for i, tag_id in enumerate(data.id) if tag_id == target_id]
|
|
256
263
|
|
|
257
264
|
if not indices:
|
|
258
|
-
SDKLogger.debug(f"No data found for tag ID {target_id} in {data_source} source")
|
|
265
|
+
# SDKLogger.debug(f"No data found for tag ID {target_id} in {data_source} source")
|
|
259
266
|
return None
|
|
260
267
|
|
|
261
268
|
return {
|
|
@@ -5,7 +5,7 @@ from kuavo_humanoid_sdk.common.global_config import GlobalConfig
|
|
|
5
5
|
from kuavo_humanoid_sdk.kuavo.core.ros_env import KuavoROSEnv, KuavoROSEnvWebsocket
|
|
6
6
|
from kuavo_humanoid_sdk.interfaces.robot import RobotBase
|
|
7
7
|
from kuavo_humanoid_sdk.common.logger import SDKLogger, disable_sdk_logging
|
|
8
|
-
from kuavo_humanoid_sdk.interfaces.data_types import KuavoPose, KuavoIKParams
|
|
8
|
+
from kuavo_humanoid_sdk.interfaces.data_types import KuavoPose, KuavoIKParams, KuavoManipulationMpcFrame, KuavoManipulationMpcCtrlMode, KuavoManipulationMpcControlFlow
|
|
9
9
|
from kuavo_humanoid_sdk.kuavo.core.core import KuavoRobotCore
|
|
10
10
|
|
|
11
11
|
from typing import Tuple
|
|
@@ -219,6 +219,46 @@ class KuavoRobot(RobotBase):
|
|
|
219
219
|
raise ValueError(f"[Robot] target_pose length must be 4 (x, y, z, yaw), but got {len(target_pose)}")
|
|
220
220
|
|
|
221
221
|
return self._kuavo_core.step_control(target_pose, dt, is_left_first_default, collision_check)
|
|
222
|
+
|
|
223
|
+
def control_command_pose(self, target_pose_x: float, target_pose_y: float, target_pose_z: float, target_pose_yaw: float) -> bool:
|
|
224
|
+
"""Control robot pose in base_link frame.
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
target_pose_x (float): The target x position in meters.
|
|
228
|
+
target_pose_y (float): The target y position in meters.
|
|
229
|
+
target_pose_z (float): The target z position in meters.
|
|
230
|
+
target_pose_yaw (float): The target yaw angle in radians.
|
|
231
|
+
|
|
232
|
+
Returns:
|
|
233
|
+
bool: True if the command was sent successfully, False otherwise.
|
|
234
|
+
|
|
235
|
+
Raises:
|
|
236
|
+
RuntimeError: If the robot is not in stance state when trying to control pose.
|
|
237
|
+
|
|
238
|
+
Note:
|
|
239
|
+
This command changes the robot state to 'command_pose'.
|
|
240
|
+
"""
|
|
241
|
+
return self._kuavo_core.control_command_pose(target_pose_x, target_pose_y, target_pose_z, target_pose_yaw)
|
|
242
|
+
|
|
243
|
+
def control_command_pose_world(self, target_pose_x: float, target_pose_y: float, target_pose_z: float, target_pose_yaw: float) -> bool:
|
|
244
|
+
"""Control robot pose in odom (world) frame.
|
|
245
|
+
|
|
246
|
+
Args:
|
|
247
|
+
target_pose_x (float): The target x position in meters.
|
|
248
|
+
target_pose_y (float): The target y position in meters.
|
|
249
|
+
target_pose_z (float): The target z position in meters.
|
|
250
|
+
target_pose_yaw (float): The target yaw angle in radians.
|
|
251
|
+
|
|
252
|
+
Returns:
|
|
253
|
+
bool: True if the command was sent successfully, False otherwise.
|
|
254
|
+
|
|
255
|
+
Raises:
|
|
256
|
+
RuntimeError: If the robot is not in stance state when trying to control pose.
|
|
257
|
+
|
|
258
|
+
Note:
|
|
259
|
+
This command changes the robot state to 'command_pose_world'.
|
|
260
|
+
"""
|
|
261
|
+
return self._kuavo_core.control_command_pose_world(target_pose_x, target_pose_y, target_pose_z, target_pose_yaw)
|
|
222
262
|
|
|
223
263
|
def control_head(self, yaw: float, pitch: float)->bool:
|
|
224
264
|
"""Control the head of the robot.
|
|
@@ -232,6 +272,16 @@ class KuavoRobot(RobotBase):
|
|
|
232
272
|
"""
|
|
233
273
|
return self._robot_head.control_head(yaw=yaw, pitch=pitch)
|
|
234
274
|
|
|
275
|
+
def enable_head_tracking(self, target_id: int)->bool:
|
|
276
|
+
"""Enable the head tracking.
|
|
277
|
+
"""
|
|
278
|
+
return self._robot_head.enable_head_tracking(target_id)
|
|
279
|
+
|
|
280
|
+
def disable_head_tracking(self)->bool:
|
|
281
|
+
"""Disable the head tracking.
|
|
282
|
+
"""
|
|
283
|
+
return self._robot_head.disable_head_tracking()
|
|
284
|
+
|
|
235
285
|
""" Robot Arm Control """
|
|
236
286
|
def arm_reset(self)->bool:
|
|
237
287
|
"""Reset the robot arm.
|
|
@@ -240,8 +290,16 @@ class KuavoRobot(RobotBase):
|
|
|
240
290
|
bool: True if the arm is reset successfully, False otherwise.
|
|
241
291
|
"""
|
|
242
292
|
return self._robot_arm.arm_reset()
|
|
293
|
+
|
|
294
|
+
def manipulation_mpc_reset(self)->bool:
|
|
295
|
+
"""Reset the robot arm.
|
|
243
296
|
|
|
244
|
-
|
|
297
|
+
Returns:
|
|
298
|
+
bool: True if the arm is reset successfully, False otherwise.
|
|
299
|
+
"""
|
|
300
|
+
return self._robot_arm.manipulation_mpc_reset()
|
|
301
|
+
|
|
302
|
+
def control_arm_joint_positions(self, joint_positions:list)->bool:
|
|
245
303
|
"""Control the position of the arm.
|
|
246
304
|
|
|
247
305
|
Args:
|
|
@@ -259,9 +317,9 @@ class KuavoRobot(RobotBase):
|
|
|
259
317
|
print("The length of the position list must be equal to the number of DOFs of the arm.")
|
|
260
318
|
return False
|
|
261
319
|
|
|
262
|
-
return self._robot_arm.
|
|
320
|
+
return self._robot_arm.control_arm_joint_positions(joint_positions)
|
|
263
321
|
|
|
264
|
-
def
|
|
322
|
+
def control_arm_joint_trajectory(self, times:list, q_frames:list)->bool:
|
|
265
323
|
"""Control the target poses of the robot arm.
|
|
266
324
|
|
|
267
325
|
Args:
|
|
@@ -281,7 +339,7 @@ class KuavoRobot(RobotBase):
|
|
|
281
339
|
This is an asynchronous interface. The function returns immediately after sending the command.
|
|
282
340
|
Users need to wait for the motion to complete on their own.
|
|
283
341
|
"""
|
|
284
|
-
return self._robot_arm.
|
|
342
|
+
return self._robot_arm.control_arm_joint_trajectory(times, q_frames)
|
|
285
343
|
|
|
286
344
|
def set_fixed_arm_mode(self) -> bool:
|
|
287
345
|
"""Freezes the robot arm.
|
|
@@ -307,6 +365,30 @@ class KuavoRobot(RobotBase):
|
|
|
307
365
|
"""
|
|
308
366
|
return self._robot_arm.set_external_control_arm_mode()
|
|
309
367
|
|
|
368
|
+
def set_manipulation_mpc_mode(self, ctrl_mode: KuavoManipulationMpcCtrlMode) -> bool:
|
|
369
|
+
"""
|
|
370
|
+
Set the manipulation mpc mode.
|
|
371
|
+
Returns:
|
|
372
|
+
bool: True if the manipulation mpc mode is set successfully, False otherwise.
|
|
373
|
+
"""
|
|
374
|
+
return self._robot_arm.set_manipulation_mpc_mode(ctrl_mode)
|
|
375
|
+
|
|
376
|
+
def set_manipulation_mpc_control_flow(self, control_flow: KuavoManipulationMpcControlFlow) -> bool:
|
|
377
|
+
"""
|
|
378
|
+
Set the manipulation mpc control flow.
|
|
379
|
+
Returns:
|
|
380
|
+
bool: True if the manipulation mpc control flow is set successfully, False otherwise.
|
|
381
|
+
"""
|
|
382
|
+
return self._robot_arm.set_manipulation_mpc_control_flow(control_flow)
|
|
383
|
+
|
|
384
|
+
def set_manipulation_mpc_frame(self, frame: KuavoManipulationMpcFrame) -> bool:
|
|
385
|
+
"""
|
|
386
|
+
Set the manipulation mpc frame.
|
|
387
|
+
Returns:
|
|
388
|
+
bool: True if the manipulation mpc frame is set successfully, False otherwise.
|
|
389
|
+
"""
|
|
390
|
+
return self._robot_arm.set_manipulation_mpc_frame(frame)
|
|
391
|
+
|
|
310
392
|
""" Arm Forward kinematics && Arm Inverse kinematics """
|
|
311
393
|
def arm_ik(self,
|
|
312
394
|
left_pose: KuavoPose,
|
|
@@ -354,4 +436,24 @@ class KuavoRobot(RobotBase):
|
|
|
354
436
|
Warning:
|
|
355
437
|
This function requires initializing the SDK with the :attr:`KuavoSDK.Options.WithIK`.
|
|
356
438
|
"""
|
|
357
|
-
return self._robot_arm.arm_fk(q)
|
|
439
|
+
return self._robot_arm.arm_fk(q)
|
|
440
|
+
|
|
441
|
+
def control_robot_end_effector_pose(self, left_pose: KuavoPose, right_pose: KuavoPose, frame: KuavoManipulationMpcFrame)->bool:
|
|
442
|
+
"""Control the end effector pose of the robot arm.
|
|
443
|
+
|
|
444
|
+
Args:
|
|
445
|
+
left_pose (KuavoPose): Pose of the robot left arm, xyz and quat.
|
|
446
|
+
right_pose (KuavoPose): Pose of the robot right arm, xyz and quat.
|
|
447
|
+
frame (KuavoManipulationMpcFrame): Frame of the robot arm.
|
|
448
|
+
|
|
449
|
+
Returns:
|
|
450
|
+
bool: True if the end effector pose is controlled successfully, False otherwise.
|
|
451
|
+
"""
|
|
452
|
+
return self._robot_arm.control_robot_end_effector_pose(left_pose, right_pose, frame)
|
|
453
|
+
|
|
454
|
+
if __name__ == "__main__":
|
|
455
|
+
robot = KuavoRobot()
|
|
456
|
+
robot.set_manipulation_mpc_mode(KuavoManipulationMpcCtrlMode.ArmOnly)
|
|
457
|
+
robot.set_manipulation_mpc_control_flow(KuavoManipulationMpcControlFlow.DirectToWbc)
|
|
458
|
+
robot.set_manipulation_mpc_frame(KuavoManipulationMpcFrame.WorldFrame)
|
|
459
|
+
robot.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)
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import math
|
|
5
5
|
from typing import Tuple
|
|
6
|
-
from kuavo_humanoid_sdk.interfaces.data_types import KuavoArmCtrlMode, KuavoIKParams, KuavoPose
|
|
6
|
+
from kuavo_humanoid_sdk.interfaces.data_types import KuavoArmCtrlMode, KuavoIKParams, KuavoPose, KuavoManipulationMpcFrame, KuavoManipulationMpcCtrlMode, KuavoManipulationMpcControlFlow
|
|
7
7
|
from kuavo_humanoid_sdk.kuavo.core.core import KuavoRobotCore
|
|
8
8
|
from kuavo_humanoid_sdk.kuavo.robot_info import KuavoRobotInfo
|
|
9
9
|
|
|
@@ -14,8 +14,11 @@ class KuavoRobotArm:
|
|
|
14
14
|
|
|
15
15
|
def arm_reset(self)-> bool:
|
|
16
16
|
return self._kuavo_core.robot_arm_reset()
|
|
17
|
+
|
|
18
|
+
def manipulation_mpc_reset(self)-> bool:
|
|
19
|
+
return self._kuavo_core.robot_manipulation_mpc_reset()
|
|
17
20
|
|
|
18
|
-
def
|
|
21
|
+
def control_arm_joint_positions(self, joint_position:list)->bool:
|
|
19
22
|
"""
|
|
20
23
|
Control the position of the robot arm joint.
|
|
21
24
|
Args:
|
|
@@ -35,9 +38,9 @@ class KuavoRobotArm:
|
|
|
35
38
|
if abs(pos) > math.pi:
|
|
36
39
|
raise ValueError(f"Joint position {pos} rad exceeds ±π rad (±180 deg) limit")
|
|
37
40
|
|
|
38
|
-
return self._kuavo_core.
|
|
41
|
+
return self._kuavo_core.control_robot_arm_joint_positions(joint_data=joint_position)
|
|
39
42
|
|
|
40
|
-
def
|
|
43
|
+
def control_arm_joint_trajectory(self, times:list, joint_q:list)->bool:
|
|
41
44
|
"""
|
|
42
45
|
Control the target poses of the robot arm.
|
|
43
46
|
Args:
|
|
@@ -51,12 +54,12 @@ class KuavoRobotArm:
|
|
|
51
54
|
Returns:
|
|
52
55
|
bool: True if the control was successful, False otherwise.
|
|
53
56
|
"""
|
|
54
|
-
if len(times) != len(
|
|
57
|
+
if len(times) != len(joint_q):
|
|
55
58
|
raise ValueError("Invalid input. times and joint_q must have thesame length.")
|
|
56
59
|
|
|
57
60
|
# Check if joint positions are within ±180 degrees (±π radians)
|
|
58
61
|
q_degs = []
|
|
59
|
-
for q in
|
|
62
|
+
for q in joint_q:
|
|
60
63
|
if any(abs(pos) > math.pi for pos in q):
|
|
61
64
|
raise ValueError("Joint positions must be within ±π rad (±180 deg)")
|
|
62
65
|
if len(q) != self._robot_info.arm_joint_dof:
|
|
@@ -64,7 +67,19 @@ class KuavoRobotArm:
|
|
|
64
67
|
# Convert joint positions from radians to degrees
|
|
65
68
|
q_degs.append([(p * 180.0 / math.pi) for p in q])
|
|
66
69
|
|
|
67
|
-
return self._kuavo_core.
|
|
70
|
+
return self._kuavo_core.control_robot_arm_joint_trajectory(times=times, joint_q=q_degs)
|
|
71
|
+
|
|
72
|
+
def control_robot_end_effector_pose(self, left_pose: KuavoPose, right_pose: KuavoPose, frame: KuavoManipulationMpcFrame)->bool:
|
|
73
|
+
"""
|
|
74
|
+
Control the end effector pose of the robot arm.
|
|
75
|
+
Args:
|
|
76
|
+
left_pose (KuavoPose): Pose of the robot left arm, xyz and quat.
|
|
77
|
+
right_pose (KuavoPose): Pose of the robot right arm, xyz and quat.
|
|
78
|
+
frame (KuavoManipulationMpcFrame): Frame of the robot end effector pose.
|
|
79
|
+
Returns:
|
|
80
|
+
bool: True if the control was successful, False otherwise.
|
|
81
|
+
"""
|
|
82
|
+
return self._kuavo_core.control_robot_end_effector_pose(left_pose, right_pose, frame)
|
|
68
83
|
|
|
69
84
|
def set_fixed_arm_mode(self) -> bool:
|
|
70
85
|
"""
|
|
@@ -90,6 +105,30 @@ class KuavoRobotArm:
|
|
|
90
105
|
"""
|
|
91
106
|
return self._kuavo_core.change_robot_arm_ctrl_mode(KuavoArmCtrlMode.ExternalControl)
|
|
92
107
|
|
|
108
|
+
def set_manipulation_mpc_mode(self, ctrl_mode: KuavoManipulationMpcCtrlMode) -> bool:
|
|
109
|
+
"""
|
|
110
|
+
Set the manipulation mpc mode.
|
|
111
|
+
Returns:
|
|
112
|
+
bool: True if the manipulation mpc mode is set successfully, False otherwise.
|
|
113
|
+
"""
|
|
114
|
+
return self._kuavo_core.change_manipulation_mpc_ctrl_mode(ctrl_mode)
|
|
115
|
+
|
|
116
|
+
def set_manipulation_mpc_control_flow(self, control_flow: KuavoManipulationMpcControlFlow) -> bool:
|
|
117
|
+
"""
|
|
118
|
+
Set the manipulation mpc control flow.
|
|
119
|
+
Returns:
|
|
120
|
+
bool: True if the manipulation mpc control flow is set successfully, False otherwise.
|
|
121
|
+
"""
|
|
122
|
+
return self._kuavo_core.change_manipulation_mpc_control_flow(control_flow)
|
|
123
|
+
|
|
124
|
+
def set_manipulation_mpc_frame(self, frame: KuavoManipulationMpcFrame) -> bool:
|
|
125
|
+
"""
|
|
126
|
+
Set the manipulation mpc frame.
|
|
127
|
+
Returns:
|
|
128
|
+
bool: True if the manipulation mpc frame is set successfully, False otherwise.
|
|
129
|
+
"""
|
|
130
|
+
return self._kuavo_core.change_manipulation_mpc_frame(frame)
|
|
131
|
+
|
|
93
132
|
""" Arm Forward kinematics && Arm Inverse kinematics """
|
|
94
133
|
def arm_ik(self,
|
|
95
134
|
left_pose: KuavoPose,
|
|
@@ -144,3 +183,10 @@ class KuavoRobotArm:
|
|
|
144
183
|
if result is None:
|
|
145
184
|
return None, None
|
|
146
185
|
return result
|
|
186
|
+
|
|
187
|
+
# if __name__ == "__main__":
|
|
188
|
+
# arm = KuavoRobotArm()
|
|
189
|
+
# arm.set_manipulation_mpc_mode(KuavoManipulationMpcCtrlMode.ArmOnly)
|
|
190
|
+
# arm.set_manipulation_mpc_control_flow(KuavoManipulationMpcControlFlow.DirectToWbc)
|
|
191
|
+
# arm.set_manipulation_mpc_frame(KuavoManipulationMpcFrame.WorldFrame)
|
|
192
|
+
# arm.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)
|
|
@@ -27,3 +27,13 @@ class KuavoRobotHead:
|
|
|
27
27
|
SDKLogger.warn(f"[Robot] pitch {pitch} exceeds limit [-{math.pi/7.2:.3f}, {math.pi/7.2:.3f}] radians (-25 to 25 degrees), will be limited")
|
|
28
28
|
limited_pitch = min(math.pi/7.2, max(-math.pi/7.2, pitch))
|
|
29
29
|
return self._kuavo_core.control_robot_head(yaw=limited_yaw, pitch=limited_pitch)
|
|
30
|
+
|
|
31
|
+
def enable_head_tracking(self, target_id: int)->bool:
|
|
32
|
+
"""Enable the head tracking.
|
|
33
|
+
"""
|
|
34
|
+
return self._kuavo_core.enable_head_tracking(target_id)
|
|
35
|
+
|
|
36
|
+
def disable_head_tracking(self)->bool:
|
|
37
|
+
"""Disable the head tracking.
|
|
38
|
+
"""
|
|
39
|
+
return self._kuavo_core.disable_head_tracking()
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
import time
|
|
4
4
|
from typing import Tuple
|
|
5
5
|
from kuavo_humanoid_sdk.interfaces.data_types import (
|
|
6
|
-
KuavoImuData, KuavoJointData, KuavoOdometry, KuavoArmCtrlMode,EndEffectorState
|
|
6
|
+
KuavoImuData, KuavoJointData, KuavoOdometry, KuavoArmCtrlMode,EndEffectorState,
|
|
7
|
+
KuavoManipulationMpcControlFlow, KuavoManipulationMpcCtrlMode, KuavoManipulationMpcFrame)
|
|
7
8
|
from kuavo_humanoid_sdk.kuavo.core.ros.state import KuavoRobotStateCore, KuavoRobotStateCoreWebsocket
|
|
8
9
|
from kuavo_humanoid_sdk.common.global_config import GlobalConfig
|
|
9
10
|
|
|
@@ -147,6 +148,31 @@ class KuavoRobotState:
|
|
|
147
148
|
"""
|
|
148
149
|
return self._rs_core.arm_control_mode
|
|
149
150
|
|
|
151
|
+
def manipulation_mpc_ctrl_mode(self) -> KuavoManipulationMpcCtrlMode:
|
|
152
|
+
"""Get the current control mode of the robot manipulation MPC.
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
KuavoManipulationMpcCtrlMode: Current manipulation MPC control mode.
|
|
156
|
+
|
|
157
|
+
"""
|
|
158
|
+
return self._rs_core.manipulation_mpc_ctrl_mode
|
|
159
|
+
|
|
160
|
+
def manipulation_mpc_control_flow(self) -> KuavoManipulationMpcControlFlow:
|
|
161
|
+
"""Get the current control flow of the robot manipulation.
|
|
162
|
+
|
|
163
|
+
Returns:
|
|
164
|
+
KuavoManipulationMpcControlFlow: Current manipulation control flow.
|
|
165
|
+
"""
|
|
166
|
+
return self._rs_core.manipulation_mpc_control_flow
|
|
167
|
+
|
|
168
|
+
def manipulation_mpc_frame(self) -> KuavoManipulationMpcFrame:
|
|
169
|
+
"""Get the current frame of the robot manipulation MPC.
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
KuavoManipulationMpcFrame: Current manipulation MPC frame.
|
|
173
|
+
"""
|
|
174
|
+
return self._rs_core.manipulation_mpc_frame
|
|
175
|
+
|
|
150
176
|
def head_joint_state(self) -> KuavoJointData:
|
|
151
177
|
"""Get the current state of the robot head joints.
|
|
152
178
|
|
|
@@ -270,4 +296,11 @@ class KuavoRobotState:
|
|
|
270
296
|
while not self._rs_core.is_gait('custom_gait') and wait_time < timeout:
|
|
271
297
|
time.sleep(0.1)
|
|
272
298
|
wait_time += 0.1
|
|
273
|
-
return self._rs_core.is_gait('custom_gait')
|
|
299
|
+
return self._rs_core.is_gait('custom_gait')
|
|
300
|
+
|
|
301
|
+
# if __name__ == "__main__":
|
|
302
|
+
# state = KuavoRobotState()
|
|
303
|
+
# print(state.manipulation_mpc_frame())
|
|
304
|
+
# print(state.manipulation_mpc_control_flow())
|
|
305
|
+
# print(state.manipulation_mpc_ctrl_mode())
|
|
306
|
+
# print(state.arm_control_mode())
|