diff --git a/device/device.go b/device/device.go index fe27b56..2f9d54f 100644 --- a/device/device.go +++ b/device/device.go @@ -21,6 +21,11 @@ type Device interface { // --- 新增 --- PoseExecutor // 嵌入 PoseExecutor 接口,Device 需实现它 GetAnimationEngine() *AnimationEngine // 获取设备的动画引擎 + + // --- 预设姿势相关方法 --- + GetSupportedPresets() []string // 获取支持的预设姿势列表 + ExecutePreset(presetName string) error // 执行预设姿势 + GetPresetDescription(presetName string) string // 获取预设姿势描述 } // Command 代表一个发送给设备的指令 diff --git a/device/models/l10.go b/device/models/l10.go index e808a76..671adc5 100644 --- a/device/models/l10.go +++ b/device/models/l10.go @@ -24,6 +24,7 @@ type L10Hand struct { mutex sync.RWMutex canInterface string // CAN 接口名称,如 "can0" animationEngine *device.AnimationEngine // 动画引擎 + presetManager *device.PresetManager // 预设姿势管理器 } // 在 base 基础上进行 ±delta 的扰动,范围限制在 [0, 255] @@ -91,6 +92,14 @@ func NewL10Hand(config map[string]any) (device.Device, error) { hand.animationEngine.Register(NewL10WaveAnimation()) hand.animationEngine.Register(NewL10SwayAnimation()) + // 初始化预设姿势管理器 + hand.presetManager = device.NewPresetManager() + + // 注册 L10 的预设姿势 + for _, preset := range GetL10Presets() { + hand.presetManager.RegisterPreset(preset) + } + // 初始化组件 if err := hand.initializeComponents(config); err != nil { return nil, fmt.Errorf("初始化组件失败:%w", err) @@ -333,3 +342,39 @@ func (h *L10Hand) Disconnect() error { log.Printf("🔌 设备 %s 已断开", h.id) return nil } + +// --- 预设姿势相关方法 --- + +// GetSupportedPresets 获取支持的预设姿势列表 +func (h *L10Hand) GetSupportedPresets() []string { return h.presetManager.GetSupportedPresets() } + +// ExecutePreset 执行预设姿势 +func (h *L10Hand) ExecutePreset(presetName string) error { + preset, exists := h.presetManager.GetPreset(presetName) + if !exists { + return fmt.Errorf("预设姿势 '%s' 不存在", presetName) + } + + log.Printf("🎯 设备 %s (%s) 执行预设姿势: %s", h.id, h.GetHandType().String(), presetName) + + // 执行手指姿态 + if err := h.SetFingerPose(preset.FingerPose); err != nil { + return fmt.Errorf("执行预设姿势 '%s' 的手指姿态失败: %w", presetName, err) + } + + // 如果有手掌姿态数据,也执行 + if len(preset.PalmPose) > 0 { + time.Sleep(20 * time.Millisecond) // 短暂延时 + if err := h.SetPalmPose(preset.PalmPose); err != nil { + return fmt.Errorf("执行预设姿势 '%s' 的手掌姿态失败: %w", presetName, err) + } + } + + log.Printf("✅ 设备 %s 预设姿势 '%s' 执行完成", h.id, presetName) + return nil +} + +// GetPresetDescription 获取预设姿势描述 +func (h *L10Hand) GetPresetDescription(presetName string) string { + return h.presetManager.GetPresetDescription(presetName) +} diff --git a/device/models/l10_presets.go b/device/models/l10_presets.go new file mode 100644 index 0000000..f8237be --- /dev/null +++ b/device/models/l10_presets.go @@ -0,0 +1,82 @@ +package models + +import "hands/device" + +// GetL10Presets 获取 L10 设备的所有预设姿势 +func GetL10Presets() []device.PresetPose { + return []device.PresetPose{ + // 基础姿势 + { + Name: "fist", + Description: "握拳姿势", + FingerPose: []byte{64, 64, 64, 64, 64, 64}, + }, + { + Name: "open", + Description: "完全张开姿势", + FingerPose: []byte{192, 192, 192, 192, 192, 192}, + }, + { + Name: "pinch", + Description: "捏取姿势", + FingerPose: []byte{120, 120, 64, 64, 64, 64}, + }, + { + Name: "thumbsup", + Description: "竖起大拇指姿势", + FingerPose: []byte{64, 192, 192, 192, 192, 64}, + }, + { + Name: "point", + Description: "食指指点姿势", + FingerPose: []byte{192, 64, 192, 192, 192, 64}, + }, + + // 数字手势 + { + Name: "1", + Description: "数字 1 手势", + FingerPose: []byte{192, 64, 192, 192, 192, 64}, + }, + { + Name: "2", + Description: "数字 2 手势", + FingerPose: []byte{192, 64, 64, 192, 192, 64}, + }, + { + Name: "3", + Description: "数字 3 手势", + FingerPose: []byte{192, 64, 64, 64, 192, 64}, + }, + { + Name: "4", + Description: "数字 4 手势", + FingerPose: []byte{192, 64, 64, 64, 64, 64}, + }, + { + Name: "5", + Description: "数字 5 手势", + FingerPose: []byte{192, 192, 192, 192, 192, 192}, + }, + { + Name: "6", + Description: "数字 6 手势", + FingerPose: []byte{64, 192, 192, 192, 192, 64}, + }, + { + Name: "7", + Description: "数字 7 手势", + FingerPose: []byte{64, 64, 192, 192, 192, 64}, + }, + { + Name: "8", + Description: "数字 8 手势", + FingerPose: []byte{64, 64, 64, 192, 192, 64}, + }, + { + Name: "9", + Description: "数字 9 手势", + FingerPose: []byte{64, 64, 64, 64, 192, 64}, + }, + } +} diff --git a/device/preset.go b/device/preset.go new file mode 100644 index 0000000..4931a39 --- /dev/null +++ b/device/preset.go @@ -0,0 +1,45 @@ +package device + +// PresetPose 定义预设姿势的结构 +type PresetPose struct { + Name string // 姿势名称 + Description string // 姿势描述 + FingerPose []byte // 手指姿态数据 + PalmPose []byte // 手掌姿态数据(可选) +} + +// PresetManager 预设姿势管理器 +type PresetManager struct{ presets map[string]PresetPose } + +// NewPresetManager 创建新的预设姿势管理器 +func NewPresetManager() *PresetManager { + return &PresetManager{ + presets: make(map[string]PresetPose), + } +} + +// RegisterPreset 注册一个预设姿势 +func (pm *PresetManager) RegisterPreset(preset PresetPose) { pm.presets[preset.Name] = preset } + +// GetPreset 获取指定名称的预设姿势 +func (pm *PresetManager) GetPreset(name string) (PresetPose, bool) { + preset, exists := pm.presets[name] + return preset, exists +} + +// GetSupportedPresets 获取所有支持的预设姿势名称列表 +func (pm *PresetManager) GetSupportedPresets() []string { + presets := make([]string, 0, len(pm.presets)) + for name := range pm.presets { + presets = append(presets, name) + } + return presets +} + +// GetPresetDescription 获取预设姿势的描述 +func (pm *PresetManager) GetPresetDescription(name string) string { + if preset, exists := pm.presets[name]; exists { + return preset.Description + } + return "" +}