mi-task/tmp/shoushi.py

189 lines
7.2 KiB
Python
Raw Normal View History

2025-08-19 22:11:14 +08:00
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import rclpy
from rclpy.node import Node
from protocol.srv import GestureActionControl
from protocol.msg import GestureActionResult
from std_srvs.srv import Trigger
import time
class GestureControlNode(Node):
def __init__(self):
super().__init__('gesture_control_node')
# 当前状态变量
self.current_state = "waiting_for_loading" # 可能的状态: waiting_for_loading, loading, transporting, waiting_for_unloading, unloading
# 创建手势控制服务客户端
self.gesture_control_cli = self.create_client(GestureActionControl, '/mi_desktop_48_b0_2d_7b_05_1d/gesture_action_control')
# 创建手势识别结果订阅
self.gesture_sub = self.create_subscription(
GestureActionResult,
'/mi_desktop_48_b0_2d_7b_05_1d/gesture_action_msg',
self.gesture_callback,
10)
# 假设存在运输开始和完成的服务
self.start_transport_cli = self.create_client(Trigger, '/mi_desktop_48_b0_2d_7b_05_1d/start_transport')
self.complete_unloading_cli = self.create_client(Trigger, '/mi_desktop_48_b0_2d_7b_05_1d/complete_unloading')
# 定时器用于状态检查
self.timer = self.create_timer(1.0, self.timer_callback)
self.get_logger().info("手势控制节点已启动")
# 手势识别超时时间(秒)
self.gesture_timeout = 60
# 最后一次检测到手势的时间
self.last_gesture_time = 0
# 激活手势识别
self.activate_gesture_recognition()
def activate_gesture_recognition(self):
"""激活手势识别功能"""
while not self.gesture_control_cli.wait_for_service(timeout_sec=1.0):
self.get_logger().info('手势控制服务不可用,等待中...')
req = GestureActionControl.Request()
req.command = GestureActionControl.Request.START_ALGO
req.timeout = self.gesture_timeout
future = self.gesture_control_cli.call_async(req)
future.add_done_callback(self.gesture_control_callback)
self.get_logger().info("已激活手势识别功能")
def gesture_control_callback(self, future):
"""手势控制服务调用回调"""
try:
response = future.result()
if response.code == GestureActionControl.Response.RESULT_SUCCESS:
self.get_logger().info("手势控制服务调用成功")
else:
self.get_logger().warn("手势控制服务繁忙")
except Exception as e:
self.get_logger().error(f"手势控制服务调用失败: {e}")
def gesture_callback(self, msg):
"""手势识别结果回调"""
self.last_gesture_time = time.time()
# 手势映射
gesture_names = {
0: "无手势",
1: "手掌拉近",
2: "手掌推开",
3: "手向上抬",
4: "手向下压",
5: "手向左推",
6: "手向右推",
7: "停止手势",
8: "大拇指朝上",
9: "张开手掌或手指",
10: "闭合手掌或手指",
11: "大拇指朝下"
}
gesture_name = gesture_names.get(msg.id, "未知手势")
self.get_logger().info(f"检测到手势: {gesture_name} (ID: {msg.id})")
# 根据当前状态和手势执行相应操作
if self.current_state == "loading" and msg.id == 8: # 大拇指朝上表示完成配货
self.complete_loading()
elif self.current_state == "unloading" and msg.id == 8: # 大拇指朝上表示完成卸货
self.complete_unloading()
elif msg.id == 7: # 停止手势
self.get_logger().info("检测到停止手势")
def complete_loading(self):
"""完成配货操作"""
self.get_logger().info("配货完成,开始运输")
# 调用开始运输服务
if self.start_transport_cli.wait_for_service(timeout_sec=1.0):
req = Trigger.Request()
future = self.start_transport_cli.call_async(req)
future.add_done_callback(self.transport_start_callback)
else:
self.get_logger().warn("开始运输服务不可用")
# 更新状态
self.current_state = "transporting"
def transport_start_callback(self, future):
"""运输开始服务回调"""
try:
response = future.result()
if response.success:
self.get_logger().info("运输已开始")
else:
self.get_logger().warn("运输启动失败")
except Exception as e:
self.get_logger().error(f"运输服务调用失败: {e}")
def complete_unloading(self):
"""完成卸货操作"""
self.get_logger().info("卸货完成,准备新的配货")
# 调用完成卸货服务
if self.complete_unloading_cli.wait_for_service(timeout_sec=1.0):
req = Trigger.Request()
future = self.complete_unloading_cli.call_async(req)
future.add_done_callback(self.unloading_complete_callback)
else:
self.get_logger().warn("完成卸货服务不可用")
# 更新状态
self.current_state = "waiting_for_loading"
def unloading_complete_callback(self, future):
"""卸货完成服务回调"""
try:
response = future.result()
if response.success:
self.get_logger().info("卸货已完成确认")
else:
self.get_logger().warn("卸货完成确认失败")
except Exception as e:
self.get_logger().error(f"卸货完成服务调用失败: {e}")
def timer_callback(self):
"""定时器回调,用于状态检查和超时处理"""
# 检查手势识别是否超时
if time.time() - self.last_gesture_time > self.gesture_timeout:
self.get_logger().info("手势识别超时,重新激活")
self.activate_gesture_recognition()
self.last_gesture_time = time.time()
# 这里可以添加状态机逻辑根据实际需求更新current_state
# 例如当机器狗到达配货区域时设置self.current_state = "loading"
# 当机器狗到达卸货区域时设置self.current_state = "unloading"
def update_state(self, new_state):
"""更新机器狗状态"""
old_state = self.current_state
self.current_state = new_state
self.get_logger().info(f"状态更新: {old_state} -> {new_state}")
# 如果进入需要手势交互的状态,确保手势识别已激活
if new_state in ["loading", "unloading"]:
self.activate_gesture_recognition()
def main(args=None):
rclpy.init(args=args)
gesture_control_node = GestureControlNode()
try:
rclpy.spin(gesture_control_node)
except KeyboardInterrupt:
pass
finally:
gesture_control_node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()