using System; using System.Threading; using System.Threading.Tasks; using System.Windows.Input; using System.Windows.Threading; using BenchMovementModule.HardwareDrive; using Logger; using UIShare.ViewModelBase; namespace BenchMovementModule.ViewModels { public class BenchMovementViewModel : NavigateViewModelBase, IRegionMemberLifetime, IDisposable { #region 属性 public bool KeepAlive => true; // ===== GantryControlTcp 实例 ===== private GantryControlTcp? _gantry; // ===== 连接状态 ===== private bool _isConnected; public bool IsConnected { get => _isConnected; set => SetProperty(ref _isConnected, value); } private string _connectionStatus = "未连接"; public string ConnectionStatus { get => _connectionStatus; set => SetProperty(ref _connectionStatus, value); } // ===== 6轴绝对位置显示(相对原点的实时位置,只读)===== private int _absPos1; public int AbsPos1 { get => _absPos1; set => SetProperty(ref _absPos1, value); } private int _absPos2; public int AbsPos2 { get => _absPos2; set => SetProperty(ref _absPos2, value); } private int _absPos3; public int AbsPos3 { get => _absPos3; set => SetProperty(ref _absPos3, value); } private int _absPos4; public int AbsPos4 { get => _absPos4; set => SetProperty(ref _absPos4, value); } private int _absPos5; public int AbsPos5 { get => _absPos5; set => SetProperty(ref _absPos5, value); } private int _absPos6; public int AbsPos6 { get => _absPos6; set => SetProperty(ref _absPos6, value); } // ===== 寸动目标位置 ===== private int _targetX; public int TargetX { get => _targetX; set => SetProperty(ref _targetX, value); } private int _targetY; public int TargetY { get => _targetY; set => SetProperty(ref _targetY, value); } private int _targetZ; public int TargetZ { get => _targetZ; set => SetProperty(ref _targetZ, value); } // ===== 扫描参数 ===== private int _scanStepX = 1000; public int ScanStepX { get => _scanStepX; set => SetProperty(ref _scanStepX, value); } private int _scanStartX; public int ScanStartX { get => _scanStartX; set => SetProperty(ref _scanStartX, value); } private int _scanEndX = 50000; public int ScanEndX { get => _scanEndX; set => SetProperty(ref _scanEndX, value); } private int _scanStepY = 1000; public int ScanStepY { get => _scanStepY; set => SetProperty(ref _scanStepY, value); } private int _scanStartY; public int ScanStartY { get => _scanStartY; set => SetProperty(ref _scanStartY, value); } private int _scanEndY = 50000; public int ScanEndY { get => _scanEndY; set => SetProperty(ref _scanEndY, value); } private int _scanStepZ = 100; public int ScanStepZ { get => _scanStepZ; set => SetProperty(ref _scanStepZ, value); } private int _scanStartZ; public int ScanStartZ { get => _scanStartZ; set => SetProperty(ref _scanStartZ, value); } private int _scanEndZ = 20000; public int ScanEndZ { get => _scanEndZ; set => SetProperty(ref _scanEndZ, value); } // ===== 速度设定(脉冲)===== private int _speedX = 5000; public int SpeedX { get => _speedX; set => SetProperty(ref _speedX, value); } private int _speedY = 5000; public int SpeedY { get => _speedY; set => SetProperty(ref _speedY, value); } private int _speedZ = 2000; public int SpeedZ { get => _speedZ; set => SetProperty(ref _speedZ, value); } private int _homeSpeed = 3000; public int HomeSpeed { get => _homeSpeed; set => SetProperty(ref _homeSpeed, value); } // ===== 零点设定 ===== private int _homeX; public int HomeX { get => _homeX; set => SetProperty(ref _homeX, value); } private int _homeY; public int HomeY { get => _homeY; set => SetProperty(ref _homeY, value); } private int _homeZ; public int HomeZ { get => _homeZ; set => SetProperty(ref _homeZ, value); } #endregion #region 命令 public ICommand OpenConfigCommand { get; } public ICommand ConnectCommand { get; } public ICommand DisconnectCommand { get; } public ICommand MoveXCommand { get; } public ICommand MoveYCommand { get; } public ICommand MoveZCommand { get; } public ICommand MoveAllCommand { get; } public ICommand GoHomeCommand { get; } public ICommand EmergencyStopCommand { get; } public ICommand StopXCommand { get; } public ICommand StopYCommand { get; } public ICommand StopZCommand { get; } public ICommand SetSpeedCommand { get; } public ICommand SetHomeCommand { get; } public ICommand ReadStatusCommand { get; } #endregion #region 私有字段 private readonly DispatcherTimer _pollTimer; private bool _isInitiated = false; #endregion public BenchMovementViewModel(IContainerProvider containerProvider) : base(containerProvider) { // 创建 GantryControlTcp 实例(默认配置,用户可通过弹窗修改) _gantry = new GantryControlTcp("192.168.0.30", 502); OpenConfigCommand = new DelegateCommand(OnOpenConfig); ConnectCommand = new DelegateCommand(OnConnect); DisconnectCommand = new DelegateCommand(OnDisconnect); MoveXCommand = new DelegateCommand(OnMoveX); MoveYCommand = new DelegateCommand(OnMoveY); MoveZCommand = new DelegateCommand(OnMoveZ); MoveAllCommand = new DelegateCommand(OnMoveAll); GoHomeCommand = new DelegateCommand(OnGoHome); EmergencyStopCommand = new DelegateCommand(OnEmergencyStop); StopXCommand = new DelegateCommand(OnStopX); StopYCommand = new DelegateCommand(OnStopY); StopZCommand = new DelegateCommand(OnStopZ); SetSpeedCommand = new DelegateCommand(OnSetSpeed); SetHomeCommand = new DelegateCommand(OnSetHome); ReadStatusCommand = new DelegateCommand(OnReadStatus); // 位置轮询定时器(500ms) _pollTimer = new DispatcherTimer(DispatcherPriority.Background) { Interval = TimeSpan.FromMilliseconds(500) }; _pollTimer.Tick += OnPollTick; } #region 命令处理 private void OnOpenConfig() { var param = new DialogParameters(); param.Add("Gantry", _gantry); _dialogService.ShowDialog("GantryConfigDialog", param, result => { UpdateConnectionStatus(); }); } private async void OnConnect() { if (_gantry == null) return; try { ConnectionStatus = "连接中..."; bool ok = await _gantry.ConnectAsync(); if (ok) { IsConnected = true; ConnectionStatus = "已连接"; _pollTimer.Start(); await ReadDeviceParametersAsync(); LoggerHelper.Info("[BenchMovement] 台架连接成功"); } else { ConnectionStatus = "连接失败"; } } catch (Exception ex) { LoggerHelper.Error($"[BenchMovement] 连接失败: {ex.Message}"); ConnectionStatus = $"连接失败: {ex.Message}"; } UpdateConnectionStatus(); } private void OnDisconnect() { if (_gantry == null) return; try { _pollTimer.Stop(); _gantry.Close(); IsConnected = false; ConnectionStatus = "未连接"; LoggerHelper.Info("[BenchMovement] 台架已断开"); } catch (Exception ex) { LoggerHelper.Error($"[BenchMovement] 断开失败: {ex.Message}"); } UpdateConnectionStatus(); } private async void OnMoveX() { if (!EnsureConnected()) return; try { await _gantry!.SetAxisTargetPositionAsync(1, TargetX); await _gantry.StartSingleAxisAsync(1); LoggerHelper.Info($"[BenchMovement] X轴移动到 {TargetX}"); } catch (Exception ex) { LoggerHelper.Error($"[BenchMovement] X轴移动失败: {ex.Message}"); ShowErrorMessageBox($"X轴移动失败: {ex.Message}", () => { }); } } private async void OnMoveY() { if (!EnsureConnected()) return; try { await _gantry!.SetAxisTargetPositionAsync(2, TargetY); await _gantry.StartSingleAxisAsync(2); LoggerHelper.Info($"[BenchMovement] Y轴移动到 {TargetY}"); } catch (Exception ex) { LoggerHelper.Error($"[BenchMovement] Y轴移动失败: {ex.Message}"); ShowErrorMessageBox($"Y轴移动失败: {ex.Message}", () => { }); } } private async void OnMoveZ() { if (!EnsureConnected()) return; try { await _gantry!.SetAxisTargetPositionAsync(3, TargetZ); await _gantry.StartSingleAxisAsync(3); LoggerHelper.Info($"[BenchMovement] Z轴移动到 {TargetZ}"); } catch (Exception ex) { LoggerHelper.Error($"[BenchMovement] Z轴移动失败: {ex.Message}"); ShowErrorMessageBox($"Z轴移动失败: {ex.Message}", () => { }); } } private async void OnMoveAll() { if (!EnsureConnected()) return; try { await _gantry!.SetAxisTargetPositionAsync(1, TargetX); await _gantry.SetAxisTargetPositionAsync(2, TargetY); await _gantry.SetAxisTargetPositionAsync(3, TargetZ); await _gantry.StartAllAxesAsync(); LoggerHelper.Info($"[BenchMovement] 三轴同时移动: X={TargetX}, Y={TargetY}, Z={TargetZ}"); } catch (Exception ex) { LoggerHelper.Error($"[BenchMovement] 三轴移动失败: {ex.Message}"); ShowErrorMessageBox($"三轴移动失败: {ex.Message}", () => { }); } } private async void OnGoHome() { if (!EnsureConnected()) return; try { await _gantry!.HomeAsync(); LoggerHelper.Info("[BenchMovement] 回原点已触发"); } catch (Exception ex) { LoggerHelper.Error($"[BenchMovement] 回原点失败: {ex.Message}"); ShowErrorMessageBox($"回原点失败: {ex.Message}", () => { }); } } private async void OnEmergencyStop() { if (!EnsureConnected()) return; try { await _gantry!.SetEStopStateAsync(true); LoggerHelper.Info("[BenchMovement] 急停已触发"); } catch (Exception ex) { LoggerHelper.Error($"[BenchMovement] 急停失败: {ex.Message}"); } } private async void OnStopX() { if (!EnsureConnected()) return; try { await _gantry!.SetStopStateAsync(1, true); await Task.Delay(100); await _gantry.SetStopStateAsync(1, false); } catch (Exception ex) { LoggerHelper.Error($"[BenchMovement] X轴停止失败: {ex.Message}"); } } private async void OnStopY() { if (!EnsureConnected()) return; try { await _gantry!.SetStopStateAsync(2, true); await Task.Delay(100); await _gantry.SetStopStateAsync(2, false); } catch (Exception ex) { LoggerHelper.Error($"[BenchMovement] Y轴停止失败: {ex.Message}"); } } private async void OnStopZ() { if (!EnsureConnected()) return; try { await _gantry!.SetStopStateAsync(3, true); await Task.Delay(100); await _gantry.SetStopStateAsync(3, false); } catch (Exception ex) { LoggerHelper.Error($"[BenchMovement] Z轴停止失败: {ex.Message}"); } } private async void OnSetSpeed() { if (!EnsureConnected()) return; try { await _gantry!.SetAxisSpeedAsync(1, SpeedX); await _gantry.SetAxisSpeedAsync(2, SpeedY); await _gantry.SetAxisSpeedAsync(3, SpeedZ); await _gantry.SetHomePositionSpeedAsync(HomeSpeed); LoggerHelper.Info($"[BenchMovement] 速度设定完成: X={SpeedX}, Y={SpeedY}, Z={SpeedZ}, 回零={HomeSpeed}"); } catch (Exception ex) { LoggerHelper.Error($"[BenchMovement] 速度设定失败: {ex.Message}"); ShowErrorMessageBox($"速度设定失败: {ex.Message}", () => { }); } } private async void OnSetHome() { if (!EnsureConnected()) return; try { await _gantry!.SetHomePositionAsync(HomeX, HomeY, HomeZ); LoggerHelper.Info($"[BenchMovement] 零点设定完成: X={HomeX}, Y={HomeY}, Z={HomeZ}"); } catch (Exception ex) { LoggerHelper.Error($"[BenchMovement] 零点设定失败: {ex.Message}"); ShowErrorMessageBox($"零点设定失败: {ex.Message}", () => { }); } } private async void OnReadStatus() { await ReadDeviceParametersAsync(); } #endregion #region 辅助方法 private bool EnsureConnected() { if (_gantry == null || !_gantry.IsConnected) { ShowErrorMessageBox("设备未连接,请先连接台架", () => { }); return false; } return true; } private void UpdateConnectionStatus() { IsConnected = _gantry?.IsConnected ?? false; ConnectionStatus = IsConnected ? "已连接" : "未连接"; } private async Task ReadDeviceParametersAsync() { if (_gantry == null || !_gantry.IsConnected) return; try { var (x, y, z) = await _gantry.GetHomePositionAsync(); HomeX = x; HomeY = y; HomeZ = z; SpeedX = await _gantry.GetAxisSpeedAsync(1); SpeedY = await _gantry.GetAxisSpeedAsync(2); SpeedZ = await _gantry.GetAxisSpeedAsync(3); HomeSpeed = await _gantry.GetHomePositionSpeedAsync(); // 读取 6 轴绝对位置 var positions = await _gantry.GetAllAbsolutePositionsAsync(); AbsPos1 = positions.Axis1; AbsPos2 = positions.Axis2; AbsPos3 = positions.Axis3; AbsPos4 = positions.Axis4; AbsPos5 = positions.Axis5; AbsPos6 = positions.Axis6; } catch (Exception ex) { LoggerHelper.Error($"[BenchMovement] 读取设备参数失败: {ex.Message}"); } } private async void OnPollTick(object? sender, EventArgs e) { if (_gantry == null || !_gantry.IsConnected) return; try { // 批量读取 6 轴绝对位置(一次性通信,高效) var pos = await _gantry.GetAllAbsolutePositionsAsync(); AbsPos1 = pos.Axis1; AbsPos2 = pos.Axis2; AbsPos3 = pos.Axis3; AbsPos4 = pos.Axis4; AbsPos5 = pos.Axis5; AbsPos6 = pos.Axis6; } catch { /* 忽略轮询错误 */ } } #endregion #region 生命周期 public override void OnNavigatedTo(NavigationContext navigationContext) { base.OnNavigatedTo(navigationContext); if (!_isInitiated) { _isInitiated = true; } } public void Dispose() { _pollTimer.Stop(); _gantry?.Close(); _gantry?.TcpDevice?.Dispose(); } #endregion } }