chore: stash temp files
This commit is contained in:
parent
228c9ca07f
commit
929ece2db1
183
cmd/hand_controller/main.go
Normal file
183
cmd/hand_controller/main.go
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"hands/pkg/config"
|
||||||
|
"hands/pkg/control"
|
||||||
|
"hands/pkg/control/modes"
|
||||||
|
"hands/pkg/device"
|
||||||
|
_ "hands/pkg/device/models" // 导入以注册设备类型
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// 解析命令行参数
|
||||||
|
configPath := flag.String("config", "config.json", "配置文件路径")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
// 加载配置
|
||||||
|
cfg, err := loadOrCreateConfig(*configPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("加载配置失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建设备管理器
|
||||||
|
deviceManager := device.NewDeviceManager()
|
||||||
|
|
||||||
|
// 创建并注册设备
|
||||||
|
for _, deviceCfg := range cfg.Devices {
|
||||||
|
dev, err := createDevice(deviceCfg, cfg.CanServiceURL)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("创建设备 %s 失败: %v", deviceCfg.ID, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := deviceManager.RegisterDevice(dev); err != nil {
|
||||||
|
log.Printf("注册设备 %s 失败: %v", deviceCfg.ID, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("成功注册设备: %s (%s)", deviceCfg.ID, deviceCfg.Model)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建操作模式管理器
|
||||||
|
modeManager := control.NewModeManager()
|
||||||
|
|
||||||
|
// 注册操作模式
|
||||||
|
modeManager.RegisterMode(modes.NewDirectPoseMode())
|
||||||
|
|
||||||
|
animFactory := modes.NewAnimationFactory()
|
||||||
|
for _, animType := range animFactory.GetSupportedAnimations() {
|
||||||
|
anim, _ := animFactory.CreateAnimation(animType)
|
||||||
|
modeManager.RegisterMode(anim)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置默认设备
|
||||||
|
if len(cfg.Devices) > 0 {
|
||||||
|
defaultDev, err := deviceManager.GetDevice(cfg.DefaultDevice.ID)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("获取默认设备失败: %v", err)
|
||||||
|
} else {
|
||||||
|
modeManager.SetDevice(defaultDev)
|
||||||
|
|
||||||
|
// 连接设备
|
||||||
|
if err := defaultDev.Connect(); err != nil {
|
||||||
|
log.Printf("连接设备失败: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Printf("成功连接设备: %s", cfg.DefaultDevice.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动默认模式
|
||||||
|
if err := modeManager.SwitchMode("DirectPose", nil); err != nil {
|
||||||
|
log.Printf("启动默认模式失败: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Println("成功启动直接姿态控制模式")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 演示功能
|
||||||
|
demonstrateFeatures(modeManager, deviceManager)
|
||||||
|
|
||||||
|
// 等待中断信号
|
||||||
|
waitForShutdown()
|
||||||
|
|
||||||
|
log.Println("应用程序正在关闭...")
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadOrCreateConfig(configPath string) (*config.Config, error) {
|
||||||
|
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
||||||
|
// 配置文件不存在,创建默认配置
|
||||||
|
cfg := config.GetDefaultConfig()
|
||||||
|
if err := config.SaveConfig(cfg, configPath); err != nil {
|
||||||
|
return nil, fmt.Errorf("保存默认配置失败:%w", err)
|
||||||
|
}
|
||||||
|
log.Printf("创建默认配置文件: %s", configPath)
|
||||||
|
return cfg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return config.LoadConfig(configPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createDevice(deviceCfg config.DeviceConfig, canServiceURL string) (device.Device, error) {
|
||||||
|
deviceConfig := map[string]interface{}{
|
||||||
|
"id": deviceCfg.ID,
|
||||||
|
"can_service_url": canServiceURL,
|
||||||
|
"can_interface": deviceCfg.CanInterface,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 合并设备特定参数
|
||||||
|
for k, v := range deviceCfg.Parameters {
|
||||||
|
deviceConfig[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
return device.CreateDevice(deviceCfg.Model, deviceConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
func demonstrateFeatures(modeManager *control.ModeManager, deviceManager *device.DeviceManager) {
|
||||||
|
log.Println("开始功能演示...")
|
||||||
|
|
||||||
|
// 演示直接姿态控制
|
||||||
|
log.Println("演示直接姿态控制...")
|
||||||
|
if activeMode := modeManager.GetActiveMode(); activeMode != nil {
|
||||||
|
if poseMode, ok := activeMode.(*modes.DirectPoseMode); ok {
|
||||||
|
// 获取设备
|
||||||
|
devices := deviceManager.GetAllDevices()
|
||||||
|
if len(devices) > 0 {
|
||||||
|
dev := devices[0]
|
||||||
|
|
||||||
|
// 发送手指姿态
|
||||||
|
fingerPoses := map[string][]byte{
|
||||||
|
"thumb": {45},
|
||||||
|
"index": {30},
|
||||||
|
"middle": {60},
|
||||||
|
"ring": {45},
|
||||||
|
"pinky": {30},
|
||||||
|
}
|
||||||
|
|
||||||
|
inputs := map[string]interface{}{
|
||||||
|
"finger_poses": fingerPoses,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := poseMode.Update(dev, inputs); err != nil {
|
||||||
|
log.Printf("发送手指姿态失败: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Println("成功发送手指姿态")
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 演示动画模式
|
||||||
|
log.Println("演示波浪动画...")
|
||||||
|
params := map[string]interface{}{
|
||||||
|
"duration": 3 * time.Second,
|
||||||
|
"frames": 30,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := modeManager.SwitchMode("Animation_wave", params); err != nil {
|
||||||
|
log.Printf("切换到波浪动画失败: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Println("成功启动波浪动画")
|
||||||
|
time.Sleep(4 * time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换回直接控制模式
|
||||||
|
if err := modeManager.SwitchMode("DirectPose", nil); err != nil {
|
||||||
|
log.Printf("切换回直接控制模式失败: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func waitForShutdown() {
|
||||||
|
sigChan := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
<-sigChan
|
||||||
|
}
|
105
pkg/config/config.go
Normal file
105
pkg/config/config.go
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Config 应用配置
|
||||||
|
type Config struct {
|
||||||
|
CanServiceURL string `json:"can_service_url"`
|
||||||
|
DefaultDevice DeviceConfig `json:"default_device"`
|
||||||
|
Devices []DeviceConfig `json:"devices"`
|
||||||
|
Server ServerConfig `json:"server"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeviceConfig 设备配置
|
||||||
|
type DeviceConfig struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Model string `json:"model"`
|
||||||
|
CanInterface string `json:"can_interface"`
|
||||||
|
Parameters map[string]interface{} `json:"parameters"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServerConfig 服务器配置
|
||||||
|
type ServerConfig struct {
|
||||||
|
Port int `json:"port"`
|
||||||
|
Host string `json:"host"`
|
||||||
|
LogLevel string `json:"log_level"`
|
||||||
|
EnableCORS bool `json:"enable_cors"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadConfig 从文件加载配置
|
||||||
|
func LoadConfig(configPath string) (*Config, error) {
|
||||||
|
file, err := os.Open(configPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("打开配置文件失败:%w", err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
var config Config
|
||||||
|
decoder := json.NewDecoder(file)
|
||||||
|
if err := decoder.Decode(&config); err != nil {
|
||||||
|
return nil, fmt.Errorf("解析配置文件失败:%w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置默认值
|
||||||
|
if config.Server.Port == 0 {
|
||||||
|
config.Server.Port = 8080
|
||||||
|
}
|
||||||
|
if config.Server.Host == "" {
|
||||||
|
config.Server.Host = "localhost"
|
||||||
|
}
|
||||||
|
if config.Server.LogLevel == "" {
|
||||||
|
config.Server.LogLevel = "info"
|
||||||
|
}
|
||||||
|
|
||||||
|
return &config, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveConfig 保存配置到文件
|
||||||
|
func SaveConfig(config *Config, configPath string) error {
|
||||||
|
file, err := os.Create(configPath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("创建配置文件失败:%w", err)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
encoder := json.NewEncoder(file)
|
||||||
|
encoder.SetIndent("", " ")
|
||||||
|
if err := encoder.Encode(config); err != nil {
|
||||||
|
return fmt.Errorf("保存配置文件失败:%w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDefaultConfig 获取默认配置
|
||||||
|
func GetDefaultConfig() *Config {
|
||||||
|
return &Config{
|
||||||
|
CanServiceURL: "http://localhost:8081",
|
||||||
|
DefaultDevice: DeviceConfig{
|
||||||
|
ID: "left_hand",
|
||||||
|
Model: "L10",
|
||||||
|
CanInterface: "can0",
|
||||||
|
Parameters: make(map[string]interface{}),
|
||||||
|
},
|
||||||
|
Devices: []DeviceConfig{
|
||||||
|
{
|
||||||
|
ID: "left_hand",
|
||||||
|
Model: "L10",
|
||||||
|
CanInterface: "can0",
|
||||||
|
Parameters: map[string]interface{}{
|
||||||
|
"hand_type": "left",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Server: ServerConfig{
|
||||||
|
Port: 8080,
|
||||||
|
Host: "localhost",
|
||||||
|
LogLevel: "info",
|
||||||
|
EnableCORS: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user