kuavo-humanoid-sdk-ws 1.2.0__20250714105233-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 (41) hide show
  1. kuavo_humanoid_sdk/__init__.py +6 -0
  2. kuavo_humanoid_sdk/common/logger.py +45 -0
  3. kuavo_humanoid_sdk/common/websocket_kuavo_sdk.py +26 -0
  4. kuavo_humanoid_sdk/interfaces/__init__.py +4 -0
  5. kuavo_humanoid_sdk/interfaces/data_types.py +293 -0
  6. kuavo_humanoid_sdk/interfaces/end_effector.py +62 -0
  7. kuavo_humanoid_sdk/interfaces/robot.py +22 -0
  8. kuavo_humanoid_sdk/interfaces/robot_info.py +56 -0
  9. kuavo_humanoid_sdk/kuavo/__init__.py +11 -0
  10. kuavo_humanoid_sdk/kuavo/core/audio.py +32 -0
  11. kuavo_humanoid_sdk/kuavo/core/core.py +602 -0
  12. kuavo_humanoid_sdk/kuavo/core/dex_hand_control.py +114 -0
  13. kuavo_humanoid_sdk/kuavo/core/leju_claw_control.py +67 -0
  14. kuavo_humanoid_sdk/kuavo/core/ros/audio.py +86 -0
  15. kuavo_humanoid_sdk/kuavo/core/ros/control.py +1045 -0
  16. kuavo_humanoid_sdk/kuavo/core/ros/observation.py +125 -0
  17. kuavo_humanoid_sdk/kuavo/core/ros/param.py +246 -0
  18. kuavo_humanoid_sdk/kuavo/core/ros/sat_utils.py +103 -0
  19. kuavo_humanoid_sdk/kuavo/core/ros/state.py +426 -0
  20. kuavo_humanoid_sdk/kuavo/core/ros/tools.py +196 -0
  21. kuavo_humanoid_sdk/kuavo/core/ros/vision.py +280 -0
  22. kuavo_humanoid_sdk/kuavo/core/ros_env.py +233 -0
  23. kuavo_humanoid_sdk/kuavo/dexterous_hand.py +198 -0
  24. kuavo_humanoid_sdk/kuavo/leju_claw.py +232 -0
  25. kuavo_humanoid_sdk/kuavo/robot.py +462 -0
  26. kuavo_humanoid_sdk/kuavo/robot_arm.py +192 -0
  27. kuavo_humanoid_sdk/kuavo/robot_audio.py +39 -0
  28. kuavo_humanoid_sdk/kuavo/robot_head.py +39 -0
  29. kuavo_humanoid_sdk/kuavo/robot_info.py +114 -0
  30. kuavo_humanoid_sdk/kuavo/robot_observation.py +69 -0
  31. kuavo_humanoid_sdk/kuavo/robot_state.py +303 -0
  32. kuavo_humanoid_sdk/kuavo/robot_tool.py +58 -0
  33. kuavo_humanoid_sdk/kuavo/robot_vision.py +82 -0
  34. kuavo_humanoid_sdk/kuavo_strategy/__init__.py +2 -0
  35. kuavo_humanoid_sdk/kuavo_strategy/grasp_box/grasp_box_strategy.py +418 -0
  36. kuavo_humanoid_sdk/kuavo_strategy/kuavo_strategy.py +63 -0
  37. kuavo_humanoid_sdk/msg/__init__.py +4 -0
  38. kuavo_humanoid_sdk_ws-1.2.0.dist-info/METADATA +276 -0
  39. kuavo_humanoid_sdk_ws-1.2.0.dist-info/RECORD +41 -0
  40. kuavo_humanoid_sdk_ws-1.2.0.dist-info/WHEEL +6 -0
  41. kuavo_humanoid_sdk_ws-1.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env python3
2
+ # coding: utf-8
3
+ from kuavo_humanoid_sdk.kuavo.core.audio import KuavoRobotAudioCore
4
+
5
+ class KuavoRobotAudio:
6
+ """Audio system interface for controlling audio playback functionality of Kuavo humanoid robot.
7
+
8
+ Provides functionality to play music files.
9
+ """
10
+
11
+ def __init__(self):
12
+ """Initialize the audio system."""
13
+ self.audio = KuavoRobotAudioCore()
14
+
15
+ def play_audio(self, file_name: str, volume: int = 100, speed: float = 1.0) -> bool:
16
+ """Play the specified audio file.
17
+
18
+ Args:
19
+ file_name (str): Name of the audio file to play
20
+
21
+ Returns:
22
+ bool: True if the play request was successfully sent, False otherwise
23
+ """
24
+ return self.audio.play_audio(file_name, volume, speed)
25
+
26
+ def stop_music(self):
27
+ """Stop the currently playing audio."""
28
+ return self.audio.stop_music()
29
+
30
+ def text_to_speech(self, text: str, volume: float = 0.5) -> bool:
31
+ """Synthesize and play the specified text.
32
+
33
+ Args:
34
+ text (str): Text to be played
35
+
36
+ Returns:
37
+ bool: True if the play request was successfully sent, False otherwise
38
+ """
39
+ return self.audio.text_to_speech(text, volume)
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env python3
2
+ # coding: utf-8
3
+ import math
4
+ from kuavo_humanoid_sdk.kuavo.core.core import KuavoRobotCore
5
+ from kuavo_humanoid_sdk.common.logger import SDKLogger
6
+
7
+ class KuavoRobotHead:
8
+ def __init__(self):
9
+ self._kuavo_core = KuavoRobotCore()
10
+
11
+ def control_head(self, yaw: float, pitch: float)->bool:
12
+ """
13
+ Control the head of the robot.
14
+ Args:
15
+ yaw (float): The yaw angle of the head in radians, range [-1.396, 1.396] (-80 to 80 degrees).
16
+ pitch (float): The pitch angle of the head in radians, range [-0.436, 0.436] (-25 to 25 degrees).
17
+ Returns:
18
+ bool: True if the head is controlled successfully, False otherwise.
19
+ """
20
+ # Check yaw limits (-80 to 80 degrees)
21
+ if yaw < -math.pi*4/9 or yaw > math.pi*4/9: # -80 to 80 degrees in radians
22
+ SDKLogger.warn(f"[Robot] yaw {yaw} exceeds limit [-{math.pi*4/9:.3f}, {math.pi*4/9:.3f}] radians (-80 to 80 degrees), will be limited")
23
+ limited_yaw = min(math.pi*4/9, max(-math.pi*4/9, yaw))
24
+
25
+ # Check pitch limits (-25 to 25 degrees)
26
+ if pitch < -math.pi/7.2 or pitch > math.pi/7.2: # -25 to 25 degrees in radians
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
+ limited_pitch = min(math.pi/7.2, max(-math.pi/7.2, pitch))
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()
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env python3
2
+ # coding: utf-8
3
+ from typing import Tuple
4
+ from kuavo_humanoid_sdk.interfaces.robot_info import RobotInfoBase
5
+ from kuavo_humanoid_sdk.kuavo.core.ros.param import RosParamWebsocket, make_robot_param
6
+
7
+ class KuavoRobotInfo(RobotInfoBase):
8
+ def __init__(self, robot_type: str = "kuavo"):
9
+ super().__init__(robot_type=robot_type)
10
+
11
+ # Load robot parameters from ROS parameter server
12
+ kuavo_ros_param = make_robot_param()
13
+ self._ros_param = RosParamWebsocket()
14
+
15
+ self._robot_version = kuavo_ros_param['robot_version']
16
+ self._end_effector_type = kuavo_ros_param['end_effector_type']
17
+ self._arm_joint_dof = kuavo_ros_param['arm_dof']
18
+ self._joint_dof = kuavo_ros_param['arm_dof'] + kuavo_ros_param['leg_dof'] + kuavo_ros_param['head_dof']
19
+ self._joint_names = kuavo_ros_param['joint_names']
20
+ self._end_frames_names = kuavo_ros_param['end_frames_names']
21
+ self._head_joint_dof = kuavo_ros_param['head_dof']
22
+ self._head_joint_names = self._joint_names[-2:]
23
+ self._arm_joint_names = self._joint_names[12:self._arm_joint_dof + 12]
24
+ @property
25
+ def robot_version(self) -> str:
26
+ """Return the version of the robot.
27
+
28
+ Returns:
29
+ str: The robot version, e.g. "42", "43"...
30
+ """
31
+ return self._robot_version
32
+
33
+ @property
34
+ def end_effector_type(self) -> str:
35
+ """Return the type of the end effector.
36
+
37
+ Returns:
38
+ str: The end effector type, where:
39
+ - "qiangnao" means "dexteroushand"
40
+ - "lejuclaw" means "lejuclaw"
41
+ - "qiangnao_touch" means "touchdexteroushand"
42
+ - ...
43
+ """
44
+ return self._end_effector_type
45
+
46
+ @property
47
+ def joint_names(self) -> list:
48
+ """Return the names of all joints in the robot.
49
+
50
+ Returns:
51
+ list: A list containing the names of all robot joints.
52
+ """
53
+ return self._joint_names
54
+
55
+ @property
56
+ def joint_dof(self) -> int:
57
+ """Return the total number of joints in the robot.
58
+
59
+ Returns:
60
+ int: Total number of joints, e.g. 28
61
+ """
62
+ return self._joint_dof
63
+
64
+ @property
65
+ def arm_joint_dof(self) -> int:
66
+ """Return the number of joints in the double-arm.
67
+
68
+ Returns:
69
+ int: Number of joints in double-arm, e.g. 14
70
+ """
71
+ return self._arm_joint_dof
72
+
73
+ @property
74
+ def arm_joint_names(self) -> list:
75
+ """Return the names of joints in the double-arm.
76
+
77
+ Returns:
78
+ list: A list containing the names of joints in the double-arm.
79
+ """
80
+ return self._arm_joint_names
81
+
82
+ @property
83
+ def head_joint_dof(self) -> int:
84
+ """Return the number of joints in the head.
85
+
86
+ Returns:
87
+ int: Number of joints in head, e.g. 2
88
+ """
89
+ return self._head_joint_dof
90
+
91
+ @property
92
+ def head_joint_names(self) -> list:
93
+ """Return the names of joints in the head.
94
+
95
+ Returns:
96
+ list: A list containing the names of joints in the head.
97
+ """
98
+ return self._head_joint_names
99
+
100
+ @property
101
+ def eef_frame_names(self) -> Tuple[str, str]:
102
+ """Returns the names of the end effector frames.
103
+
104
+ Returns:
105
+ Tuple[str, str]:
106
+ A tuple containing the end effector frame names, where:
107
+ - First element is the left hand frame name
108
+ - Second element is the right hand frame name
109
+ e.g. ("zarm_l7_link", "zarm_r7_link")
110
+ """
111
+ return self._end_frames_names[1], self._end_frames_names[2]
112
+
113
+ def __str__(self) -> str:
114
+ return f"KuavoRobotInfo(robot_type={self.robot_type}, robot_version={self.robot_version}, end_effector_type={self.end_effector_type}, joint_names={self.joint_names}, joint_dof={self.joint_dof}, arm_joint_dof={self.arm_joint_dof})"
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env python3
2
+ # coding: utf-8
3
+ from kuavo_humanoid_sdk.interfaces.data_types import (
4
+ KuavoJointCommand, KuavoTwist)
5
+ from kuavo_humanoid_sdk.kuavo.core.ros.observation import KuavoRobotObservationCoreWebsocket
6
+
7
+ class KuavoRobotObservation:
8
+ """Class for accessing robot observation data.
9
+
10
+ This class provides a high-level interface to access robot observation data,
11
+ including joint commands, velocity commands, and pose commands.
12
+
13
+ Attributes:
14
+ _obs_core: The core observation object that handles ROS communication.
15
+ """
16
+
17
+ def __init__(self, robot_type: str = "kuavo"):
18
+ """Initialize the robot observation interface.
19
+
20
+ Args:
21
+ robot_type (str): Type of the robot. Defaults to "kuavo".
22
+ """
23
+ self._obs_core = KuavoRobotObservationCoreWebsocket()
24
+
25
+ @property
26
+ def joint_command(self) -> KuavoJointCommand:
27
+ """Get the current joint command.
28
+
29
+ Returns:
30
+ KuavoJointCommand: Object containing position, velocity, and torque commands
31
+ for all robot joints.
32
+ """
33
+ return self._obs_core.joint_command
34
+
35
+ @property
36
+ def cmd_vel(self) -> KuavoTwist:
37
+ """Get the current velocity command.
38
+
39
+ Returns:
40
+ KuavoTwist: Object containing linear velocity (m/s) and angular velocity (rad/s) commands.
41
+ """
42
+ return self._obs_core.cmd_vel
43
+
44
+ @property
45
+ def cmd_pose(self) -> KuavoTwist:
46
+ """Get the current pose command.
47
+
48
+ Returns:
49
+ KuavoTwist: Object containing linear pose commands (m) and angular pose commands (rad).
50
+ """
51
+ return self._obs_core.cmd_pose
52
+
53
+ @property
54
+ def arm_position_command(self) -> list:
55
+ """Get the position commands for the arm joints.
56
+
57
+ Returns:
58
+ list: Position commands for arm joints (indices 12-25) in radians.
59
+ """
60
+ return self._obs_core.arm_position_command
61
+
62
+ @property
63
+ def head_position_command(self) -> list:
64
+ """Get the position commands for the head joints.
65
+
66
+ Returns:
67
+ list: Position commands for head joints (indices 26-27) in radians.
68
+ """
69
+ return self._obs_core.head_position_command
@@ -0,0 +1,303 @@
1
+ #!/usr/bin/env python3
2
+ # coding: utf-8
3
+ import time
4
+ import copy
5
+ from typing import Tuple
6
+ from kuavo_humanoid_sdk.interfaces.data_types import (
7
+ KuavoImuData, KuavoJointData, KuavoOdometry, KuavoArmCtrlMode,EndEffectorState,
8
+ KuavoManipulationMpcControlFlow, KuavoManipulationMpcCtrlMode, KuavoManipulationMpcFrame)
9
+ from kuavo_humanoid_sdk.kuavo.core.ros.state import KuavoRobotStateCoreWebsocket
10
+
11
+ class KuavoRobotState:
12
+ def __init__(self, robot_type: str = "kuavo"):
13
+ self._rs_core = KuavoRobotStateCoreWebsocket()
14
+
15
+ @property
16
+ def imu_data(self) -> KuavoImuData:
17
+ """Get Robot IMU Data.
18
+
19
+ Gets the current IMU sensor data from the robot, including gyroscope, accelerometer,
20
+ free acceleration and orientation quaternion measurements.
21
+
22
+ Returns:
23
+ :class:`KuavoImuData`: IMU data containing:
24
+ * gyro (:obj:`tuple` of :obj:`float`): Gyroscope measurements (x, y, z) in rad/s
25
+ * acc (:obj:`tuple` of :obj:`float`): Accelerometer measurements (x, y, z) in m/s^2
26
+ * free_acc (:obj:`tuple` of :obj:`float`): Free acceleration (x, y, z) in m/s^2
27
+ * quat (:obj:`tuple` of :obj:`float`): Orientation quaternion (x, y, z, w)
28
+ """
29
+ return self._rs_core.imu_data
30
+
31
+ @property
32
+ def joint_state(self) -> KuavoJointData:
33
+ """Get Robot Joint Data.
34
+
35
+ Get Robot Joint Data, including joint positions, velocities, torques and accelerations.
36
+
37
+ The data includes:
38
+ - Joint positions (angles) in radians
39
+ - Joint velocities in radians/second
40
+ - Joint torques/efforts in Newton-meters, A
41
+ - Joint acceleration
42
+
43
+ Returns:
44
+ KuavoJointData: A dictionary containing joint state data with the following keys:
45
+ position (list[float]): Joint positions, length = joint_dof(28)
46
+ velocity (list[float]): Joint velocities, length = joint_dof(28)
47
+ torque (list[float]): Joint torques, length = joint_dof(28)
48
+ acceleration (list[float]): Joint accelerations, length = joint_dof(28)
49
+ """
50
+ return self._rs_core.joint_data
51
+
52
+ @property
53
+ def com_height(self)->float:
54
+ """Get the height of the robot's center of mass.
55
+
56
+ Returns:
57
+ float: The height of the robot's center of mass in meters.
58
+ """
59
+ return self._rs_core.com_height
60
+
61
+ @property
62
+ def odometry(self) -> KuavoOdometry:
63
+ """Get Robot Odometry Data.
64
+
65
+ Gets the current odometry data from the robot, including position, orientation,
66
+ linear velocity and angular velocity measurements.
67
+
68
+ Returns:
69
+ KuavoOdometry: A dictionary containing odometry data with the following keys:
70
+ position (tuple): Position (x, y, z) in meters
71
+ orientation (tuple): Orientation as quaternion (x, y, z, w)
72
+ linear (tuple): Linear velocity (x, y, z) in m/s
73
+ angular (tuple): Angular velocity (x, y, z) in rad/s
74
+ """
75
+ return self._rs_core.odom_data
76
+
77
+
78
+ def robot_position(self) -> Tuple[float, float, float]:
79
+ """Returns the robot's position in world coordinates.
80
+
81
+ Returns:
82
+ Tuple[float, float, float]: Position (x, y, z) in meters.
83
+ """
84
+ return tuple(self._rs_core.odom_data.position)
85
+
86
+ def robot_orientation(self) -> Tuple[float, float, float, float]:
87
+ """Returns the robot's orientation in world coordinates.
88
+
89
+ Returns:
90
+ Tuple[float, float, float, float]: Orientation as quaternion (x, y, z, w).
91
+ """
92
+ return tuple(self._rs_core.odom_data.orientation)
93
+
94
+ def linear_velocity(self) -> Tuple[float, float, float]:
95
+ """Returns the robot's linear velocity in world coordinates.
96
+
97
+ Returns:
98
+ Tuple[float, float, float]: Linear velocity (x, y, z) in m/s.
99
+ """
100
+ return tuple(self._rs_core.odom_data.linear)
101
+
102
+
103
+ def angular_velocity(self) -> Tuple[float, float, float]:
104
+ """Returns the robot's angular velocity in world coordinates.
105
+
106
+ Returns:
107
+ Tuple[float, float, float]: Angular velocity (x, y, z).
108
+ """
109
+ return tuple(self._rs_core.odom_data.angular)
110
+
111
+ def arm_joint_state(self) -> KuavoJointData:
112
+ """Get the current state of the robot arm joints.
113
+
114
+ Get the current state of the robot arm joints, including:
115
+ - Joint positions (angles) in radians
116
+ - Joint velocities in radians/second
117
+ - Joint torques/efforts in Newton-meters, A
118
+ - Joint acceleration
119
+
120
+ Returns:
121
+ KuavoJointData: Arm joint data containing:
122
+ position: list[float] * arm_dof(14)
123
+ velocity: list[float] * arm_dof(14)
124
+ torque: list[float] * arm_dof(14)
125
+ acceleration: list[float] * arm_dof(14)
126
+ """
127
+ # Get arm joint states from index 12 to 25 (14 arm joints)
128
+ arm_joint_indices = range(12, 12+14)
129
+ return KuavoJointData(
130
+ position=[self._rs_core.joint_data.position[i] for i in arm_joint_indices],
131
+ velocity=[self._rs_core.joint_data.velocity[i] for i in arm_joint_indices],
132
+ torque=[self._rs_core.joint_data.torque[i] for i in arm_joint_indices],
133
+ acceleration=[self._rs_core.joint_data.acceleration[i] for i in arm_joint_indices]
134
+ )
135
+
136
+ def arm_control_mode(self) -> KuavoArmCtrlMode:
137
+ """Get the current control mode of the robot arm.
138
+
139
+ Returns:
140
+ KuavoArmCtrlMode: Current arm control mode:
141
+ ArmFixed: 0 - The robot arm is in a fixed position.
142
+ AutoSwing: 1 - The robot arm is in automatic swing mode.
143
+ ExternalControl: 2 - The robot arm is controlled externally.
144
+ or None.
145
+ """
146
+ return KuavoArmCtrlMode(self._rs_core.arm_control_mode)
147
+
148
+ def manipulation_mpc_ctrl_mode(self) -> KuavoManipulationMpcCtrlMode:
149
+ """Get the current control mode of the robot manipulation MPC.
150
+
151
+ Returns:
152
+ KuavoManipulationMpcCtrlMode: Current manipulation MPC control mode.
153
+
154
+ """
155
+ return self._rs_core.manipulation_mpc_ctrl_mode
156
+
157
+ def manipulation_mpc_control_flow(self) -> KuavoManipulationMpcControlFlow:
158
+ """Get the current control flow of the robot manipulation.
159
+
160
+ Returns:
161
+ KuavoManipulationMpcControlFlow: Current manipulation control flow.
162
+ """
163
+ return self._rs_core.manipulation_mpc_control_flow
164
+
165
+ def manipulation_mpc_frame(self) -> KuavoManipulationMpcFrame:
166
+ """Get the current frame of the robot manipulation MPC.
167
+
168
+ Returns:
169
+ KuavoManipulationMpcFrame: Current manipulation MPC frame.
170
+ """
171
+ return self._rs_core.manipulation_mpc_frame
172
+
173
+ def head_joint_state(self) -> KuavoJointData:
174
+ """Get the current state of the robot head joints.
175
+
176
+ Gets the current state data for the robot's head joints, including position,
177
+ velocity, torque and acceleration values.
178
+
179
+ Returns:
180
+ KuavoJointData: A data structure containing the head joint states:
181
+ position (list[float]): Joint positions in radians, length=head_dof(2)
182
+ velocity (list[float]): Joint velocities in rad/s, length=head_dof(2)
183
+ torque (list[float]): Joint torques in Nm, length=head_dof(2)
184
+ acceleration (list[float]): Joint accelerations in rad/s^2, length=head_dof(2)
185
+
186
+ The joint order is [yaw, pitch].
187
+ """
188
+ # Get head joint states from last 2 indices
189
+ head_joint_indices = range(len(self._rs_core.joint_data.position)-2, len(self._rs_core.joint_data.position))
190
+ return KuavoJointData(
191
+ position=[self._rs_core.joint_data.position[i] for i in head_joint_indices],
192
+ velocity=[self._rs_core.joint_data.velocity[i] for i in head_joint_indices],
193
+ torque=[self._rs_core.joint_data.torque[i] for i in head_joint_indices],
194
+ acceleration=[self._rs_core.joint_data.acceleration[i] for i in head_joint_indices]
195
+ )
196
+
197
+ def eef_state(self)->Tuple[EndEffectorState, EndEffectorState]:
198
+ """Get the current state of the robot's end effectors.
199
+
200
+ Returns:
201
+ Tuple[EndEffectorState, EndEffectorState]: A tuple containing the state of the left and right end effectors.
202
+ Each EndEffectorState contains:
203
+ - position: (float, float, float) - XYZ position in meters
204
+ - orientation: (float, float, float, float) - Quaternion orientation
205
+ - state: EndEffectorState.GraspingState - Current grasping state (UNKNOWN, OPEN, CLOSED)
206
+ """
207
+ return copy.deepcopy(self._rs_core.eef_state)
208
+
209
+ def gait_name(self)->str:
210
+ """Get the current gait name of the robot.
211
+
212
+ Returns:
213
+ str: The name of the current gait, e.g. 'trot', 'walk', 'stance', 'custom_gait'.
214
+ """
215
+ return self._rs_core.gait_name()
216
+
217
+
218
+ def is_stance(self) -> bool:
219
+ """Check if the robot is currently in stance mode.
220
+
221
+ Returns:
222
+ bool: True if robot is in stance mode, False otherwise.
223
+ """
224
+ return self._rs_core.is_gait('stance')
225
+
226
+ def is_walk(self) -> bool:
227
+ """Check if the robot is currently in walk mode.
228
+
229
+ Returns:
230
+ bool: True if robot is in walk mode, False otherwise.
231
+ """
232
+ return self._rs_core.is_gait('walk')
233
+
234
+ def is_step_control(self) -> bool:
235
+ """Check if the robot is currently in step control mode.
236
+
237
+ Returns:
238
+ bool: True if robot is in step control mode, False otherwise.
239
+ """
240
+ return self._rs_core.is_gait('custom_gait')
241
+
242
+ def wait_for_stance(self, timeout:float=5.0)->bool:
243
+ """Wait for the robot to enter stance state.
244
+
245
+ Args:
246
+ timeout (float): The maximum time to wait for the robot to enter stance state in seconds.
247
+
248
+ Returns:
249
+ bool: True if the robot enters stance state within the specified timeout, False otherwise.
250
+ """
251
+ wait_time = 0
252
+ while not self._rs_core.is_gait('stance') and wait_time < timeout:
253
+ time.sleep(0.1)
254
+ wait_time += 0.1
255
+ return self._rs_core.is_gait('stance')
256
+
257
+ def wait_for_trot(self, timeout:float=5.0)->bool:
258
+ """Wait for the robot to enter trot state.
259
+
260
+ Args:
261
+ timeout (float): The maximum time to wait for the robot to enter trot state in seconds.
262
+
263
+ Returns:
264
+ bool: True if the robot enters trot state within the specified timeout, False otherwise.
265
+ """
266
+ return self.wait_for_walk(timeout=timeout)
267
+
268
+ def wait_for_walk(self, timeout:float=5.0)->bool:
269
+ """Wait for the robot to enter walk state.
270
+
271
+ Args:
272
+ timeout (float): The maximum time to wait for the robot to enter walk state in seconds.
273
+
274
+ Returns:
275
+ bool: True if the robot enters walk state within the specified timeout, False otherwise.
276
+ """
277
+ wait_time = 0
278
+ while not self._rs_core.is_gait('walk') and wait_time < timeout:
279
+ time.sleep(0.1)
280
+ wait_time += 0.1
281
+ return self._rs_core.is_gait('walk')
282
+
283
+ def wait_for_step_control(self, timeout:float=5.0)->bool:
284
+ """Wait for the robot to enter step control state.
285
+
286
+ Args:
287
+ timeout (float): The maximum time to wait for the robot to enter step control state in seconds.
288
+
289
+ Returns:
290
+ bool: True if the robot enters step control state within the specified timeout, False otherwise.
291
+ """
292
+ wait_time = 0
293
+ while not self._rs_core.is_gait('custom_gait') and wait_time < timeout:
294
+ time.sleep(0.1)
295
+ wait_time += 0.1
296
+ return self._rs_core.is_gait('custom_gait')
297
+
298
+ # if __name__ == "__main__":
299
+ # state = KuavoRobotState()
300
+ # print(state.manipulation_mpc_frame())
301
+ # print(state.manipulation_mpc_control_flow())
302
+ # print(state.manipulation_mpc_ctrl_mode())
303
+ # print(state.arm_control_mode())
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env python3
2
+ # coding: utf-8
3
+ import math
4
+ from kuavo_humanoid_sdk.common.logger import SDKLogger
5
+ from kuavo_humanoid_sdk.interfaces.data_types import (PoseQuaternion, HomogeneousMatrix)
6
+ from kuavo_humanoid_sdk.kuavo.core.ros.tools import KuavoRobotToolsCoreWebsocket
7
+ from typing import Union
8
+
9
+ class KuavoRobotTools:
10
+ """机器人工具类,提供坐标系转换接口。
11
+
12
+ 该类封装了不同机器人坐标系之间的坐标变换查询功能,支持多种返回数据格式。
13
+ """
14
+
15
+ def __init__(self):
16
+ self.tools_core = KuavoRobotToolsCoreWebsocket()
17
+
18
+ def get_tf_transform(self, target_frame: str, source_frame: str,
19
+ return_type: str = "pose_quaternion") -> Union[PoseQuaternion, HomogeneousMatrix, None]:
20
+ """获取指定坐标系之间的变换。
21
+
22
+ Args:
23
+ target_frame (str): 目标坐标系名称
24
+ source_frame (str): 源坐标系名称
25
+ return_type (str, optional): 返回数据格式类型。有效值: \n
26
+ - "pose_quaternion" : 四元数姿态格式, \n
27
+ - "homogeneous" : 齐次矩阵格式。默认为"pose_quaternion"。\n
28
+
29
+ Returns:
30
+ Union[PoseQuaternion, HomogeneousMatrix, None]:
31
+ 指定格式的变换数据,如果失败则返回None
32
+
33
+ Raises:
34
+ ValueError: 如果提供了无效的 return_type
35
+ """
36
+ return self.tools_core._get_tf_tree_transform(target_frame, source_frame, return_type=return_type)
37
+
38
+ def get_base_to_odom(self, return_type: str = "pose_quaternion") -> Union[PoseQuaternion, HomogeneousMatrix, None]:
39
+ """获取从base_link到odom坐标系的变换。
40
+
41
+ Args:
42
+ return_type (str, optional): 返回格式类型。与get_tf_transform相同,默认为"pose_quaternion"。
43
+
44
+ Returns:
45
+ Union[PoseQuaternion, HomogeneousMatrix, None]: 变换数据或 None
46
+ """
47
+ return self.get_tf_transform("odom", "base_link", return_type)
48
+
49
+ def get_camera_to_base(self, return_type: str = "homogeneous") -> Union[PoseQuaternion, HomogeneousMatrix, None]:
50
+ """获取从camera_link到base_link坐标系的变换。
51
+
52
+ Args:
53
+ return_type (str, optional): 返回格式类型。与get_tf_transform相同,默认为"homogeneous"。
54
+
55
+ Returns:
56
+ Union[PoseQuaternion, HomogeneousMatrix, None]: 变换数据或None
57
+ """
58
+ return self.get_tf_transform("base_link", "camera_link", return_type)