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.
- kuavo_humanoid_sdk/__init__.py +0 -2
- kuavo_humanoid_sdk/interfaces/data_types.py +0 -90
- kuavo_humanoid_sdk/kuavo/__init__.py +0 -3
- kuavo_humanoid_sdk/kuavo/core/core.py +20 -238
- kuavo_humanoid_sdk/kuavo/core/ros/control.py +27 -1087
- kuavo_humanoid_sdk/kuavo/core/ros/param.py +4 -142
- kuavo_humanoid_sdk/kuavo/core/ros/state.py +19 -556
- kuavo_humanoid_sdk/kuavo/core/ros_env.py +1 -229
- kuavo_humanoid_sdk/kuavo/dexterous_hand.py +2 -6
- kuavo_humanoid_sdk/kuavo/leju_claw.py +2 -6
- kuavo_humanoid_sdk/kuavo/robot.py +27 -150
- kuavo_humanoid_sdk/kuavo/robot_arm.py +7 -53
- kuavo_humanoid_sdk/kuavo/robot_head.py +0 -10
- kuavo_humanoid_sdk/kuavo/robot_info.py +2 -7
- kuavo_humanoid_sdk/kuavo/robot_state.py +4 -41
- kuavo_humanoid_sdk/msg/kuavo_msgs/msg/__init__.py +0 -7
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/__init__.py +0 -5
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_playmusic.py +20 -26
- kuavo_humanoid_sdk/msg/motion_capture_ik/msg/__init__.py +9 -0
- kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/msg/_armHandPose.py +2 -2
- kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/msg/_handPose.py +2 -2
- kuavo_humanoid_sdk/msg/motion_capture_ik/msg/_headBodyPose.py +145 -0
- kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/msg/_ikSolveError.py +13 -13
- kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/msg/_ikSolveParam.py +2 -2
- kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/msg/_robotArmQVVD.py +2 -2
- kuavo_humanoid_sdk/msg/motion_capture_ik/msg/_robotHandPosition.py +225 -0
- kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/msg/_twoArmHandPose.py +13 -13
- kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/msg/_twoArmHandPoseCmd.py +30 -34
- kuavo_humanoid_sdk/msg/motion_capture_ik/srv/__init__.py +4 -0
- kuavo_humanoid_sdk/msg/{kuavo_msgs/srv/_setMmCtrlFrame.py → motion_capture_ik/srv/_changeArmCtrlMode.py} +37 -35
- kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/srv/_changeArmCtrlModeKuavo.py +5 -5
- kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/srv/_fkSrv.py +13 -13
- kuavo_humanoid_sdk/msg/{kuavo_msgs → motion_capture_ik}/srv/_twoArmHandPoseCmdSrv.py +37 -38
- {kuavo_humanoid_sdk-1.1.5.dist-info → kuavo_humanoid_sdk-1.1.6.dist-info}/METADATA +1 -2
- {kuavo_humanoid_sdk-1.1.5.dist-info → kuavo_humanoid_sdk-1.1.6.dist-info}/RECORD +37 -46
- kuavo_humanoid_sdk/common/global_config.py +0 -16
- kuavo_humanoid_sdk/common/websocket_kuavo_sdk.py +0 -23
- kuavo_humanoid_sdk/kuavo/core/audio.py +0 -36
- kuavo_humanoid_sdk/kuavo/core/ros/audio.py +0 -176
- kuavo_humanoid_sdk/kuavo/core/ros/tools.py +0 -158
- kuavo_humanoid_sdk/kuavo/core/ros/vision.py +0 -283
- kuavo_humanoid_sdk/kuavo/robot_audio.py +0 -39
- kuavo_humanoid_sdk/kuavo/robot_tool.py +0 -62
- kuavo_humanoid_sdk/kuavo/robot_vision.py +0 -90
- kuavo_humanoid_sdk/kuavo_strategy/__init__.py +0 -2
- kuavo_humanoid_sdk/kuavo_strategy/grasp_box/grasp_box_strategy.py +0 -418
- kuavo_humanoid_sdk/kuavo_strategy/kuavo_strategy.py +0 -63
- kuavo_humanoid_sdk/msg/kuavo_msgs/srv/_SpeechSynthesis.py +0 -270
- {kuavo_humanoid_sdk-1.1.5.dist-info → kuavo_humanoid_sdk-1.1.6.dist-info}/WHEEL +0 -0
- {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
|
|
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.
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
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
|
-
|
|
960
|
-
|
|
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
|
-
|
|
1350
|
-
|
|
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
|
|
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
|
|
626
|
+
def control_robot_arm_target_poses(self, times:list, joint_q:list)->bool:
|
|
1380
627
|
"""
|
|
1381
|
-
Control robot arm
|
|
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
|
+
""" ------------------------------------------------------------------------------"""
|