kuavo-humanoid-sdk-ws 1.3.2__20260122221834-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.
Files changed (43) hide show
  1. kuavo_humanoid_sdk/__init__.py +6 -0
  2. kuavo_humanoid_sdk/common/launch_robot_tool.py +170 -0
  3. kuavo_humanoid_sdk/common/logger.py +45 -0
  4. kuavo_humanoid_sdk/common/websocket_kuavo_sdk.py +26 -0
  5. kuavo_humanoid_sdk/interfaces/__init__.py +4 -0
  6. kuavo_humanoid_sdk/interfaces/data_types.py +293 -0
  7. kuavo_humanoid_sdk/interfaces/end_effector.py +62 -0
  8. kuavo_humanoid_sdk/interfaces/robot.py +22 -0
  9. kuavo_humanoid_sdk/interfaces/robot_info.py +56 -0
  10. kuavo_humanoid_sdk/kuavo/__init__.py +12 -0
  11. kuavo_humanoid_sdk/kuavo/core/audio.py +32 -0
  12. kuavo_humanoid_sdk/kuavo/core/core.py +755 -0
  13. kuavo_humanoid_sdk/kuavo/core/dex_hand_control.py +114 -0
  14. kuavo_humanoid_sdk/kuavo/core/leju_claw_control.py +67 -0
  15. kuavo_humanoid_sdk/kuavo/core/ros/audio.py +86 -0
  16. kuavo_humanoid_sdk/kuavo/core/ros/control.py +1325 -0
  17. kuavo_humanoid_sdk/kuavo/core/ros/observation.py +125 -0
  18. kuavo_humanoid_sdk/kuavo/core/ros/param.py +335 -0
  19. kuavo_humanoid_sdk/kuavo/core/ros/sat_utils.py +103 -0
  20. kuavo_humanoid_sdk/kuavo/core/ros/state.py +426 -0
  21. kuavo_humanoid_sdk/kuavo/core/ros/tools.py +197 -0
  22. kuavo_humanoid_sdk/kuavo/core/ros/vision.py +280 -0
  23. kuavo_humanoid_sdk/kuavo/core/ros_env.py +236 -0
  24. kuavo_humanoid_sdk/kuavo/dexterous_hand.py +198 -0
  25. kuavo_humanoid_sdk/kuavo/leju_claw.py +232 -0
  26. kuavo_humanoid_sdk/kuavo/robot.py +550 -0
  27. kuavo_humanoid_sdk/kuavo/robot_arm.py +235 -0
  28. kuavo_humanoid_sdk/kuavo/robot_audio.py +39 -0
  29. kuavo_humanoid_sdk/kuavo/robot_head.py +39 -0
  30. kuavo_humanoid_sdk/kuavo/robot_info.py +235 -0
  31. kuavo_humanoid_sdk/kuavo/robot_observation.py +69 -0
  32. kuavo_humanoid_sdk/kuavo/robot_state.py +346 -0
  33. kuavo_humanoid_sdk/kuavo/robot_tool.py +58 -0
  34. kuavo_humanoid_sdk/kuavo/robot_vision.py +82 -0
  35. kuavo_humanoid_sdk/kuavo/robot_waist.py +53 -0
  36. kuavo_humanoid_sdk/kuavo_strategy/__init__.py +2 -0
  37. kuavo_humanoid_sdk/kuavo_strategy/grasp_box/grasp_box_strategy.py +418 -0
  38. kuavo_humanoid_sdk/kuavo_strategy/kuavo_strategy.py +63 -0
  39. kuavo_humanoid_sdk/msg/__init__.py +4 -0
  40. kuavo_humanoid_sdk_ws-1.3.2.dist-info/METADATA +276 -0
  41. kuavo_humanoid_sdk_ws-1.3.2.dist-info/RECORD +43 -0
  42. kuavo_humanoid_sdk_ws-1.3.2.dist-info/WHEEL +6 -0
  43. kuavo_humanoid_sdk_ws-1.3.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,550 @@
1
+ #!/usr/bin/env python3
2
+ # coding: utf-8
3
+ from kuavo_humanoid_sdk.kuavo.core.ros_env import KuavoROSEnvWebsocket
4
+ from kuavo_humanoid_sdk.interfaces.robot import RobotBase
5
+ from kuavo_humanoid_sdk.common.logger import SDKLogger, disable_sdk_logging
6
+ from kuavo_humanoid_sdk.interfaces.data_types import KuavoPose, KuavoIKParams, KuavoManipulationMpcFrame, KuavoManipulationMpcCtrlMode, KuavoManipulationMpcControlFlow
7
+ from kuavo_humanoid_sdk.kuavo.core.core import KuavoRobotCore
8
+
9
+ from typing import Tuple
10
+ from kuavo_humanoid_sdk.kuavo.robot_info import KuavoRobotInfo
11
+ from kuavo_humanoid_sdk.kuavo.robot_arm import KuavoRobotArm
12
+ from kuavo_humanoid_sdk.kuavo.robot_head import KuavoRobotHead
13
+ from kuavo_humanoid_sdk.kuavo.robot_waist import KuavoRobotWaist
14
+ from kuavo_humanoid_sdk.common.websocket_kuavo_sdk import WebSocketKuavoSDK
15
+ from kuavo_humanoid_sdk.common.launch_robot_tool import LaunchRobotTool
16
+
17
+ """
18
+ Kuavo SDK - Python Interface for Kuavo Robot Control
19
+
20
+ This module provides the main interface for controlling Kuavo robots through Python.
21
+ It includes two main classes:
22
+
23
+ KuavoSDK:
24
+ A static class providing SDK initialization and configuration functionality.
25
+ Handles core setup, ROS environment initialization, and logging configuration.
26
+
27
+ KuavoRobot:
28
+ The main robot control interface class that provides access to:
29
+ - Robot information and status (via KuavoRobotInfo)
30
+ - Arm control capabilities (via KuavoRobotArm)
31
+ - Head control capabilities (via KuavoRobotHead)
32
+ - Core robot functions (via KuavoRobotCore)
33
+
34
+ The module requires a properly configured ROS environment to function.
35
+ """
36
+ __all__ = ["KuavoSDK", "KuavoRobot"]
37
+
38
+
39
+ class KuavoSDK:
40
+ class Options:
41
+ Normal = 0x01
42
+ WithIK = 0x02
43
+
44
+ def __init__(self):
45
+ pass
46
+
47
+ @staticmethod
48
+ def Init(options:int=Options.Normal, log_level: str = "INFO",
49
+ websocket_mode: bool = False, websocket_host='127.0.0.1', websocket_port=9090, websocket_timeout=5)-> bool:
50
+ """Initialize the SDK.
51
+
52
+ Initializes the Kuavo SDK with specified options and configuration.
53
+
54
+ Args:
55
+ options (int): Configuration options for the SDK. Use KuavoSDK.Options constants.
56
+ Defaults to Options.Normal.
57
+ log_level (str): Logging level to use. Options are "ERROR", "WARN", "INFO", "DEBUG".
58
+ Defaults to "INFO".
59
+ websocket_mode (bool): Whether to use websocket mode for ROS communication.
60
+ If True, connects to ROS through websocket instead of direct connection.
61
+ Defaults to False.
62
+ websocket_host (str): Host address of the rosbridge websocket server.
63
+ Only used when websocket_mode is True. Defaults to "127.0.0.1".
64
+ websocket_port (int): Port number of the rosbridge websocket server.
65
+ Only used when websocket_mode is True. Defaults to 9090.
66
+ websocket_timeout (int): Timeout in seconds for the websocket connection.
67
+ Defaults to 5.
68
+
69
+ Returns:
70
+ bool: True if initialization succeeds, False otherwise.
71
+
72
+ Raises:
73
+ RuntimeError: If initialization fails due to missing dependencies or
74
+ connection issues.
75
+ """
76
+ WebSocketKuavoSDK.use_websocket = websocket_mode
77
+ WebSocketKuavoSDK.websocket_host = websocket_host
78
+ WebSocketKuavoSDK.websocket_port = websocket_port
79
+ WebSocketKuavoSDK.websocket_timeout = websocket_timeout
80
+ SDKLogger.setLevel(log_level.upper())
81
+ SDKLogger.debug(f" ================= Kuavo Humanoid Websocket SDK =================")
82
+
83
+ def launch_robot()->bool:
84
+ import time
85
+ import os
86
+ start_time = time.time()
87
+ launch_robot_tool = LaunchRobotTool()
88
+
89
+ # 获取机器人启动状态
90
+ success, status = launch_robot_tool.get_robot_launch_status()
91
+ if not success:
92
+ # 可能websocket服务未启动或网络不通原因
93
+ SDKLogger.error(f"[SDK] Failed to get robot launch status: {status}")
94
+ return False
95
+
96
+ SDKLogger.info(f"[SDK] Robot launch status: {status}, time elapsed: {time.time() - start_time:.2f}s")
97
+
98
+ # 如果机器人已经启动,则直接返回True
99
+ if launch_robot_tool.is_launched(status):
100
+ return True
101
+
102
+ # 未启动则启动
103
+ if launch_robot_tool.is_unlaunch(status):
104
+ print("\033[32m\n>_ 温馨提示: 机器人未启动,现在可以选择手动启动,如果需要请输入 y ,否则输入 n 退出\033[0m")
105
+ try:
106
+ while True:
107
+ choice = input().lower()
108
+ if choice == 'y':
109
+ if not launch_robot_tool.robot_start():
110
+ SDKLogger.error("机器人启动失败,请检查机器人状态")
111
+ os._exit(1)
112
+ break
113
+ elif choice == 'n':
114
+ SDKLogger.warning("用户选择不启动机器人,程序退出。")
115
+ os._exit(1)
116
+ else:
117
+ SDKLogger.error("输入错误,请输入 y 或 n")
118
+ except KeyboardInterrupt:
119
+ os._exit(1)
120
+
121
+ SDKLogger.debug(f"等待机器人启动,已耗时: {time.time() - start_time:.2f}s")
122
+
123
+ if not launch_robot_tool.robot_stand():
124
+ SDKLogger.error("机器人站立失败,请检查机器人状态")
125
+ os._exit(1)
126
+
127
+ end_time = time.time()
128
+ SDKLogger.info(f"[SDK] Robot launch time: {end_time - start_time} seconds")
129
+ return True
130
+
131
+ # Launch robot
132
+ if not launch_robot():
133
+ SDKLogger.error("[SDK] Failed to launch robot.")
134
+ return False
135
+
136
+ # Initialize core components, connect ROS Topics...
137
+ kuavo_core = KuavoRobotCore()
138
+ if log_level.upper() == 'DEBUG':
139
+ debug = True
140
+ else:
141
+ debug = False
142
+ # Check if IK option is enabled
143
+ if options & KuavoSDK.Options.WithIK:
144
+ if not KuavoROSEnvWebsocket.check_rosnode_exists('/arms_ik_node'):
145
+ print("\033[31m\nError:WithIK option is enabled but ik_node is not running, please run `roslaunch motion_capture_ik ik_node.launch`\033[0m")
146
+ exit(1)
147
+
148
+ if not kuavo_core.initialize(debug=debug):
149
+ SDKLogger.error("[SDK] Failed to initialize core components.")
150
+ return False
151
+
152
+ return True
153
+
154
+ @staticmethod
155
+ def DisableLogging():
156
+ """Disable all logging output from the SDK."""
157
+ disable_sdk_logging()
158
+
159
+ @staticmethod
160
+ def StopRobot()->bool:
161
+ """Stop the robot."""
162
+ launch_robot_tool = LaunchRobotTool()
163
+ success, status = launch_robot_tool.get_robot_launch_status()
164
+ if not success:
165
+ SDKLogger.error(f"[SDK] Failed to get robot launch status: {status}")
166
+ return False
167
+ if launch_robot_tool.is_unlaunch(status):
168
+ return True
169
+ return launch_robot_tool.robot_stop()
170
+
171
+ class KuavoRobot(RobotBase):
172
+ def __init__(self):
173
+ super().__init__(robot_type="kuavo")
174
+
175
+ kuavo_ros_env = KuavoROSEnvWebsocket()
176
+ if not kuavo_ros_env.Init():
177
+ raise RuntimeError("Failed to initialize ROS environment")
178
+
179
+ self._robot_info = KuavoRobotInfo()
180
+ self._robot_arm = KuavoRobotArm()
181
+ self._robot_head = KuavoRobotHead()
182
+ self._robot_waist = KuavoRobotWaist()
183
+ self._kuavo_core = KuavoRobotCore()
184
+ def stance(self)->bool:
185
+ """Put the robot into 'stance' mode.
186
+
187
+ Returns:
188
+ bool: True if the robot is put into stance mode successfully, False otherwise.
189
+
190
+ Note:
191
+ You can call :meth:`KuavoRobotState.wait_for_stance` to wait until the robot enters stance mode.
192
+ """
193
+ return self._kuavo_core.to_stance()
194
+
195
+ def trot(self)->bool:
196
+ """Put the robot into 'trot' mode.
197
+
198
+ Returns:
199
+ bool: True if the robot is put into trot mode successfully, False otherwise.
200
+
201
+ Note:
202
+ You can call :meth:`KuavoRobotState.wait_for_walk` to wait until the robot enters trot mode.
203
+ """
204
+ return self._kuavo_core.to_trot()
205
+
206
+ def walk(self, linear_x:float, linear_y:float, angular_z:float)->bool:
207
+ """Control the robot's motion.
208
+
209
+ Args:
210
+ linear_x (float): The linear velocity along the x-axis in m/s, range [-0.4, 0.4].
211
+ linear_y (float): The linear velocity along the y-axis in m/s, range [-0.2, 0.2].
212
+ angular_z (float): The angular velocity around the z-axis in rad/s, range [-0.4, 0.4].
213
+
214
+ Returns:
215
+ bool: True if the motion is controlled successfully, False otherwise.
216
+
217
+ Note:
218
+ You can call :meth:`KuavoRobotState.wait_for_walk` to wait until the robot enters walk mode.
219
+ """
220
+ return self._kuavo_core.walk(linear_x, linear_y, angular_z)
221
+
222
+ def jump(self):
223
+ """Jump the robot."""
224
+ pass
225
+
226
+ def squat(self, height: float, pitch: float=0.0)->bool:
227
+ """Control the robot's squat height and pitch.
228
+ Args:
229
+ height (float): The height offset from normal standing height in meters, range [-0.35, 0.1],Negative values indicate squatting down.
230
+ Normal standing height reference: :attr:KuavoRobotInfo.init_stand_height
231
+ pitch (float): The pitch angle of the robot's torso in radians, range [0.0, 0.4].
232
+
233
+ Returns:
234
+ bool: True if the squat is controlled successfully, False otherwise.
235
+
236
+ Note:
237
+ Down squat and stand up should not change too fast, the maximum change should not exceed 0.2 meters.
238
+ """
239
+ return self._kuavo_core.squat(height, pitch)
240
+
241
+ def step_by_step(self, target_pose:list, dt:float=0.4, is_left_first_default:bool=True, collision_check:bool=True)->bool:
242
+ """Control the robot's motion by step.
243
+
244
+ Args:
245
+ target_pose (list): The target position of the robot in [x, y, z, yaw] m, rad.
246
+ dt (float): The time interval between each step in seconds. Defaults to 0.4s.
247
+ is_left_first_default (bool): Whether to start with the left foot. Defaults to True.
248
+ collision_check (bool): Whether to check for collisions. Defaults to True.
249
+
250
+ Returns:
251
+ bool: True if motion is successful, False otherwise.
252
+
253
+ Raises:
254
+ RuntimeError: If the robot is not in stance state when trying to control step motion.
255
+ ValueError: If target_pose length is not 4.
256
+
257
+ Note:
258
+ You can call :meth:`KuavoRobotState.wait_for_step_control` to wait until the robot enters step-control mode.
259
+ You can call :meth:`KuavoRobotState.wait_for_stance` to wait the step-control finish.
260
+
261
+ Warning:
262
+ If the current robot's torso height is too low (less than -0.15m relative to normal standing height), the function will return False.
263
+ Normal standing height reference: :attr:KuavoRobotInfo.init_stand_height
264
+ """
265
+ if len(target_pose) != 4:
266
+ raise ValueError(f"[Robot] target_pose length must be 4 (x, y, z, yaw), but got {len(target_pose)}")
267
+
268
+ return self._kuavo_core.step_control(target_pose, dt, is_left_first_default, collision_check)
269
+
270
+ def control_command_pose(self, target_pose_x: float, target_pose_y: float, target_pose_z: float, target_pose_yaw: float) -> bool:
271
+ """Control robot pose in base_link frame.
272
+
273
+ Args:
274
+ target_pose_x (float): The target x position in meters.
275
+ target_pose_y (float): The target y position in meters.
276
+ target_pose_z (float): The target z position in meters.
277
+ target_pose_yaw (float): The target yaw angle in radians.
278
+
279
+ Returns:
280
+ bool: True if the command was sent successfully, False otherwise.
281
+
282
+ Raises:
283
+ RuntimeError: If the robot is not in stance state when trying to control pose.
284
+
285
+ Note:
286
+ This command changes the robot state to 'command_pose'.
287
+ """
288
+ return self._kuavo_core.control_command_pose(target_pose_x, target_pose_y, target_pose_z, target_pose_yaw)
289
+
290
+ def control_command_pose_world(self, target_pose_x: float, target_pose_y: float, target_pose_z: float, target_pose_yaw: float) -> bool:
291
+ """Control robot pose in odom (world) frame.
292
+
293
+ Args:
294
+ target_pose_x (float): The target x position in meters.
295
+ target_pose_y (float): The target y position in meters.
296
+ target_pose_z (float): The target z position in meters.
297
+ target_pose_yaw (float): The target yaw angle in radians.
298
+
299
+ Returns:
300
+ bool: True if the command was sent successfully, False otherwise.
301
+
302
+ Raises:
303
+ RuntimeError: If the robot is not in stance state when trying to control pose.
304
+
305
+ Note:
306
+ This command changes the robot state to 'command_pose_world'.
307
+ """
308
+ return self._kuavo_core.control_command_pose_world(target_pose_x, target_pose_y, target_pose_z, target_pose_yaw)
309
+
310
+ def control_head(self, yaw: float, pitch: float)->bool:
311
+ """Control the head of the robot.
312
+
313
+ Args:
314
+ yaw (float): The yaw angle of the head in radians, range [-1.396, 1.396] (-80 to 80 degrees).
315
+ pitch (float): The pitch angle of the head in radians, range [-0.436, 0.436] (-25 to 25 degrees).
316
+
317
+ Returns:
318
+ bool: True if the head is controlled successfully, False otherwise.
319
+ """
320
+ return self._robot_head.control_head(yaw=yaw, pitch=pitch)
321
+
322
+ def enable_head_tracking(self, target_id: int)->bool:
323
+ """Enable the head tracking.
324
+ """
325
+ return self._robot_head.enable_head_tracking(target_id)
326
+
327
+ def disable_head_tracking(self)->bool:
328
+ """Disable the head tracking.
329
+ """
330
+ return self._robot_head.disable_head_tracking()
331
+
332
+ def control_waist(self, yaw: float) -> bool:
333
+ """Control the waist of the robot.
334
+
335
+ Args:
336
+ yaw (float): The yaw angle of the waist in **degrees**.
337
+ Recommended range [-180, 180] degrees.
338
+ Values outside this range will be automatically limited.
339
+
340
+ Returns:
341
+ bool: True if the waist is controlled successfully, False otherwise.
342
+ """
343
+ return self._robot_waist.control_waist(yaw=yaw)
344
+
345
+ """ Robot Arm Control """
346
+ def arm_reset(self)->bool:
347
+ """Reset the robot arm.
348
+
349
+ Returns:
350
+ bool: True if the arm is reset successfully, False otherwise.
351
+ """
352
+ return self._robot_arm.arm_reset()
353
+
354
+ def manipulation_mpc_reset(self)->bool:
355
+ """Reset the robot arm.
356
+
357
+ Returns:
358
+ bool: True if the arm is reset successfully, False otherwise.
359
+ """
360
+ return self._robot_arm.manipulation_mpc_reset()
361
+
362
+ def control_arm_joint_positions(self, joint_positions:list)->bool:
363
+ """Control the position of the arm.
364
+
365
+ Args:
366
+ joint_positions (list): The target position of the arm in radians.
367
+
368
+ Returns:
369
+ bool: True if the arm is controlled successfully, False otherwise.
370
+
371
+ Raises:
372
+ ValueError: If the joint position list is not of the correct length.
373
+ ValueError: If the joint position is outside the range of [-π, π].
374
+ RuntimeError: If the robot is not in stance state when trying to control the arm.
375
+ """
376
+ if len(joint_positions) != self._robot_info.arm_joint_dof:
377
+ print("The length of the position list must be equal to the number of DOFs of the arm.")
378
+ return False
379
+
380
+ return self._robot_arm.control_arm_joint_positions(joint_positions)
381
+
382
+ def control_arm_joint_trajectory(self, times:list, q_frames:list)->bool:
383
+ """Control the target poses of the robot arm.
384
+
385
+ Args:
386
+ times (list): List of time intervals in seconds.
387
+ q_frames (list): List of joint positions in radians.
388
+
389
+ Returns:
390
+ bool: True if the control was successful, False otherwise.
391
+
392
+ Raises:
393
+ ValueError: If the times list is not of the correct length.
394
+ ValueError: If the joint position list is not of the correct length.
395
+ ValueError: If the joint position is outside the range of [-π, π].
396
+ RuntimeError: If the robot is not in stance state when trying to control the arm.
397
+
398
+ Warning:
399
+ This is an asynchronous interface. The function returns immediately after sending the command.
400
+ Users need to wait for the motion to complete on their own.
401
+ """
402
+ return self._robot_arm.control_arm_joint_trajectory(times, q_frames)
403
+
404
+ def set_fixed_arm_mode(self) -> bool:
405
+ """Freezes the robot arm.
406
+
407
+ Returns:
408
+ bool: True if the arm is frozen successfully, False otherwise.
409
+ """
410
+ return self._robot_arm.set_fixed_arm_mode()
411
+
412
+ def set_auto_swing_arm_mode(self) -> bool:
413
+ """Swing the robot arm.
414
+
415
+ Returns:
416
+ bool: True if the arm is swinging successfully, False otherwise.
417
+ """
418
+ return self._robot_arm.set_auto_swing_arm_mode()
419
+
420
+ def set_external_control_arm_mode(self) -> bool:
421
+ """External control the robot arm.
422
+
423
+ Returns:
424
+ bool: True if the arm is external controlled successfully, False otherwise.
425
+ """
426
+ return self._robot_arm.set_external_control_arm_mode()
427
+
428
+ def set_manipulation_mpc_mode(self, ctrl_mode: KuavoManipulationMpcCtrlMode) -> bool:
429
+ """
430
+ Set the manipulation mpc mode.
431
+ Returns:
432
+ bool: True if the manipulation mpc mode is set successfully, False otherwise.
433
+ """
434
+ return self._robot_arm.set_manipulation_mpc_mode(ctrl_mode)
435
+
436
+ def set_manipulation_mpc_control_flow(self, control_flow: KuavoManipulationMpcControlFlow) -> bool:
437
+ """
438
+ Set the manipulation mpc control flow.
439
+ Returns:
440
+ bool: True if the manipulation mpc control flow is set successfully, False otherwise.
441
+ """
442
+ return self._robot_arm.set_manipulation_mpc_control_flow(control_flow)
443
+
444
+ def set_manipulation_mpc_frame(self, frame: KuavoManipulationMpcFrame) -> bool:
445
+ """
446
+ Set the manipulation mpc frame.
447
+ Returns:
448
+ bool: True if the manipulation mpc frame is set successfully, False otherwise.
449
+ """
450
+ return self._robot_arm.set_manipulation_mpc_frame(frame)
451
+
452
+ """ Arm Forward kinematics && Arm Inverse kinematics """
453
+ def arm_ik(self,
454
+ left_pose: KuavoPose,
455
+ right_pose: KuavoPose,
456
+ left_elbow_pos_xyz: list = [0.0, 0.0, 0.0],
457
+ right_elbow_pos_xyz: list = [0.0, 0.0, 0.0],
458
+ arm_q0: list = None,
459
+ params: KuavoIKParams=None) -> list:
460
+ """Inverse kinematics for the robot arm.
461
+
462
+ Args:
463
+ left_pose (KuavoPose): Pose of the robot left arm, xyz and quat.
464
+ right_pose (KuavoPose): Pose of the robot right arm, xyz and quat.
465
+ left_elbow_pos_xyz (list): Position of the robot left elbow. If [0.0, 0.0, 0.0], will be ignored.
466
+ right_elbow_pos_xyz (list): Position of the robot right elbow. If [0.0, 0.0, 0.0], will be ignored.
467
+ arm_q0 (list, optional): Initial joint positions in radians. If None, will be ignored.
468
+ params (KuavoIKParams, optional): Parameters for the inverse kinematics. If None, will be ignored.
469
+ Contains:
470
+ - major_optimality_tol: Major optimality tolerance
471
+ - major_feasibility_tol: Major feasibility tolerance
472
+ - minor_feasibility_tol: Minor feasibility tolerance
473
+ - major_iterations_limit: Major iterations limit
474
+ - oritation_constraint_tol: Orientation constraint tolerance
475
+ - pos_constraint_tol: Position constraint tolerance, works when pos_cost_weight==0.0
476
+ - pos_cost_weight: Position cost weight. Set to 0.0 for high accuracy
477
+
478
+ Returns:
479
+ list: List of joint positions in radians, or None if inverse kinematics failed.
480
+
481
+ Warning:
482
+ This function requires initializing the SDK with the :attr:`KuavoSDK.Options.WithIK`.
483
+ """
484
+ return self._robot_arm.arm_ik(left_pose, right_pose, left_elbow_pos_xyz, right_elbow_pos_xyz, arm_q0, params)
485
+
486
+ def arm_fk(self, q: list) -> Tuple[KuavoPose, KuavoPose]:
487
+ """Forward kinematics for the robot arm.
488
+
489
+ Args:
490
+ q (list): List of joint positions in radians.
491
+
492
+ Returns:
493
+ Tuple[KuavoPose, KuavoPose]: Tuple of poses for the robot left arm and right arm,
494
+ or (None, None) if forward kinematics failed.
495
+
496
+ Warning:
497
+ This function requires initializing the SDK with the :attr:`KuavoSDK.Options.WithIK`.
498
+ """
499
+ return self._robot_arm.arm_fk(q)
500
+
501
+ def control_robot_end_effector_pose(self, left_pose: KuavoPose, right_pose: KuavoPose, frame: KuavoManipulationMpcFrame)->bool:
502
+ """Control the end effector pose of the robot arm.
503
+
504
+ Args:
505
+ left_pose (KuavoPose): Pose of the robot left arm, xyz and quat.
506
+ right_pose (KuavoPose): Pose of the robot right arm, xyz and quat.
507
+ frame (KuavoManipulationMpcFrame): Frame of the robot arm.
508
+
509
+ Returns:
510
+ bool: True if the end effector pose is controlled successfully, False otherwise.
511
+ """
512
+ return self._robot_arm.control_robot_end_effector_pose(left_pose, right_pose, frame)
513
+
514
+ def is_arm_collision(self)->bool:
515
+ """Check if the arm is in collision.
516
+
517
+ Returns:
518
+ bool: True if the arm is in collision, False otherwise.
519
+ """
520
+ return self._robot_arm.is_arm_collision()
521
+
522
+ def is_arm_collision_mode(self)->bool:
523
+ """Check if arm collision mode is enabled.
524
+
525
+ Returns:
526
+ bool: True if collision mode is enabled, False otherwise.
527
+ """
528
+ return self._robot_arm.is_arm_collision_mode()
529
+
530
+ def wait_arm_collision_complete(self):
531
+ """Wait for the arm collision to complete.
532
+ """
533
+ self._robot_arm.wait_arm_collision_complete()
534
+
535
+ def release_arm_collision_mode(self):
536
+ """Release the arm collision mode.
537
+ """
538
+ self._robot_arm.release_arm_collision_mode()
539
+
540
+ def set_arm_collision_mode(self, enable: bool):
541
+ """Set the arm collision mode.
542
+ """
543
+ self._robot_arm.set_arm_collision_mode(enable)
544
+
545
+ if __name__ == "__main__":
546
+ robot = KuavoRobot()
547
+ robot.set_manipulation_mpc_mode(KuavoManipulationMpcCtrlMode.ArmOnly)
548
+ robot.set_manipulation_mpc_control_flow(KuavoManipulationMpcControlFlow.DirectToWbc)
549
+ robot.set_manipulation_mpc_frame(KuavoManipulationMpcFrame.WorldFrame)
550
+ 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)