using MaterialDesignThemes.Wpf; using Prism.Commands; using Prism.Events; using Prism.Ioc; using Prism.Mvvm; using Prism.Regions; using Prism.Services.Dialogs; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Windows; using TeamAAS_VP.Core; using TeamAAS_VP.Core.PLCs; using TeamAAS_VP.DxfModule; using TeamAAS_VP.Enums; using TeamAAS_VP.Events; using TeamAAS_VP.Interfaces; using TeamAAS_VP.Models; using TeamAAS_VP.Models.PLC; using TeamAAS_VP.Models.Robot; using TeamAAS_VP.Resources.Languages; using TeamAAS_VP.Views.Product; namespace TeamAAS_VP.ViewModels.Product { public class PlcPointParamsViewModel : BindableBase, IConfirmNavigationRequest { IRegionManager _regionManager; IEventAggregator _eventAggregator; IContainerProvider _container; IDialogService _dialogService; IConfigService _configService; IRobotService _robotService; ISystemDatabaseService _systemDatabaseService; #region 属性 private ProductModel _SelectProduct; /// /// 选中的产品 /// public ProductModel SelectProduct { get { return _SelectProduct; } set { SetProperty(ref _SelectProduct, value); } } private PlcPoint _SelectedPoint; public PlcPoint SelectedPoint { get { return _SelectedPoint; } set { SetProperty(ref _SelectedPoint, value); } } private PlcPoint _selectedPointInDataGrid; public PlcPoint SelectedPointInDataGrid { get { return _selectedPointInDataGrid; } set { if (SetProperty(ref _selectedPointInDataGrid, value)) { SelectedPointInComboBox = value; // update command availability _MovePointUpCommand?.RaiseCanExecuteChanged(); _MovePointDownCommand?.RaiseCanExecuteChanged(); // 更新依赖可执行状态的命令 _TechPointCommand?.RaiseCanExecuteChanged(); _ExecuteMotion?.RaiseCanExecuteChanged(); } // 可以同步到 SelectPoint 属性 SelectedPoint = value; } } private PlcPoint _selectedPointInComboBox; public PlcPoint SelectedPointInComboBox { get { return _selectedPointInComboBox; } set { if (SetProperty(ref _selectedPointInComboBox, value)) { SelectedPointInDataGrid = value; } // 可以同步到 SelectPoint 属性 SelectedPoint = value; } } private ObservableCollection _Points = new ObservableCollection(); /// /// 点位集合 /// public ObservableCollection Points { get { return _Points; } set { SetProperty(ref _Points, value); } } private MotionCommand _SelectMotionCommand; /// /// 选中的运动指令 /// public MotionCommand SelectMotionCommand { get { return _SelectMotionCommand; } set { SetProperty(ref _SelectMotionCommand, value); } } public Management management { get; set; } private IRobot _Robot; public IRobot Robot { get { return _Robot; } set { SetProperty(ref _Robot, value); } } private int _SelectedIndex; public int SelectedIndex { get { return _SelectedIndex; } set { SetProperty(ref _SelectedIndex, value); } } private double _Distance = 1; public double Distance { get { return _Distance; } set { SetProperty(ref _Distance, value); try { if (Robot == null) { return; } _configService.UpdateRobotStepDistance(Robot.Id, value); } catch (Exception) { } } } #endregion #region 命令 private DelegateCommand _NextCommand; public DelegateCommand NextCommand => _NextCommand ?? (_NextCommand = new DelegateCommand(ExecuteNextCommand)); private DelegateCommand _BackCommand; public DelegateCommand BackCommand => _BackCommand ?? (_BackCommand = new DelegateCommand(ExecuteBackCommand)); private DelegateCommand _LoadedCommand; public DelegateCommand LoadedCommand => _LoadedCommand ?? (_LoadedCommand = new DelegateCommand(ExecuteLoadedCommand)); private DelegateCommand _ExecuteMotion; public DelegateCommand ExecuteMotion => _ExecuteMotion ?? (_ExecuteMotion = new DelegateCommand(ExecuteExecuteMotion).ObservesCanExecute(() => CanExecute).ObservesProperty(() => Robot).ObservesProperty(() => Robot.CanExecute).ObservesProperty(() => SelectedPointInDataGrid)); private DelegateCommand _JogCommand; public DelegateCommand JogCommand => _JogCommand ?? (_JogCommand = new DelegateCommand(ExecuteJogCommand).ObservesCanExecute(() => CanExecute).ObservesProperty(() => Robot).ObservesProperty(() => Robot.CanExecute)); private DelegateCommand _TechPointCommand; public DelegateCommand TechPointCommand => _TechPointCommand ?? (_TechPointCommand = new DelegateCommand(ExecuteTechPointCommand).ObservesCanExecute(() => CanExecute).ObservesProperty(() => Robot).ObservesProperty(() => Robot.CanExecute).ObservesProperty(() => SelectedPointInDataGrid)); private DelegateCommand _MotorCommand; public DelegateCommand MotorCommand => _MotorCommand ?? (_MotorCommand = new DelegateCommand(ExecuteMotorCommand).ObservesCanExecute(() => CanExecute).ObservesProperty(() => Robot).ObservesProperty(() => Robot.CanExecute)); private DelegateCommand _ResetCommand; public DelegateCommand ResetCommand => _ResetCommand ?? (_ResetCommand = new DelegateCommand(ExecuteResetCommand).ObservesCanExecute(() => CanExecute).ObservesProperty(() => Robot).ObservesProperty(() => Robot.CanExecute)); private DelegateCommand _sFreeCommand; public DelegateCommand sFreeCommand => _sFreeCommand ?? (_sFreeCommand = new DelegateCommand(ExecutesFreeCommand).ObservesCanExecute(() => CanExecute).ObservesProperty(() => Robot).ObservesProperty(() => Robot.CanExecute)); private DelegateCommand _SLockCommand; public DelegateCommand SLockCommand => _SLockCommand ?? (_SLockCommand = new DelegateCommand(ExecuteSLockCommand).ObservesCanExecute(() => CanExecute).ObservesProperty(() => Robot).ObservesProperty(() => Robot.CanExecute)); private DelegateCommand _SelectionChangedCommand; public DelegateCommand SelectionChangedCommand => _SelectionChangedCommand ?? (_SelectionChangedCommand = new DelegateCommand(ExecuteSelectionChangedCommand)); private DelegateCommand _AddPointCommand; public DelegateCommand AddPointCommand => _AddPointCommand ?? (_AddPointCommand = new DelegateCommand(ExecuteAddPointCommand)); private DelegateCommand _DeletePointCommand; public DelegateCommand DeletePointCommand => _DeletePointCommand ?? (_DeletePointCommand = new DelegateCommand(ExecuteDeletePointCommand)); private DelegateCommand _MovePointUpCommand; public DelegateCommand MovePointUpCommand => _MovePointUpCommand ?? (_MovePointUpCommand = new DelegateCommand(ExecuteMovePointUpCommand, CanMovePointUp)); private DelegateCommand _MovePointDownCommand; public DelegateCommand MovePointDownCommand => _MovePointDownCommand ?? (_MovePointDownCommand = new DelegateCommand(ExecuteMovePointDownCommand, CanMovePointDown)); private DelegateCommand _ImportCadPointCommand; public DelegateCommand ImportCadPointCommand => _ImportCadPointCommand ?? (_ImportCadPointCommand = new DelegateCommand(ExecuteImportCadPointCommand)); #endregion #region 事件 #endregion public PlcPointParamsViewModel(IRegionManager regionManager, IEventAggregator ea, IContainerProvider container, IDialogService dialogService, IConfigService configService, IRobotService robotService, ISystemDatabaseService systemDatabaseService) { _regionManager = regionManager; _eventAggregator = ea; _container = container; _dialogService = dialogService; _configService = configService; _systemDatabaseService = systemDatabaseService; //订阅权限登录事件 _eventAggregator.GetEvent().Subscribe(LoginChange); management = _container.Resolve(); _robotService = robotService; } #region 方法 /// /// 下一步 /// void ExecuteNextCommand() { NavigationParameters param = new NavigationParameters(); param.Add("SelectProduct", SelectProduct); _regionManager.RequestNavigate("ProductRegionContext", "ProductParams", param); } /// /// 上一步 /// void ExecuteBackCommand() { NavigationParameters param = new NavigationParameters(); param.Add("SelectProduct", SelectProduct); param.Add("SelectedProcedure", null); _regionManager.RequestNavigate("ProductRegionContext", "ProcessBasics", param); } /// /// 点动 /// /// private async void ExecuteJogCommand(object obj) { if (Robot == null || !Robot.IsConnected) return; try { Robot.Timeout = 6000000; var items = ((string)obj).Split(':'); switch (items[0]) { case "X+": await Robot.JogAsync("X", double.Parse(items[1])); break; case "X-": await Robot.JogAsync("X", -double.Parse(items[1])); break; case "Y+": await Robot.JogAsync("Y", double.Parse(items[1])); break; case "Y-": await Robot.JogAsync("Y", -double.Parse(items[1])); break; case "Z+": await Robot.JogAsync("Z", double.Parse(items[1])); break; case "Z-": await Robot.JogAsync("Z", -double.Parse(items[1])); break; case "U+": await Robot.JogAsync("U", double.Parse(items[1])); break; case "U-": await Robot.JogAsync("U", -double.Parse(items[1])); break; case "V+": await Robot.JogAsync("V", double.Parse(items[1])); break; case "V-": await Robot.JogAsync("V", -double.Parse(items[1])); break; case "W+": await Robot.JogAsync("W", double.Parse(items[1])); break; case "W-": await Robot.JogAsync("W", -double.Parse(items[1])); break; default: break; } Robot.Timeout = 5000; _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = $"{Lang.完成}!", Duration = 0.4 }); } catch (Exception ex) { LogHelper.WriteLogError("机器人点位-机器人点动时出错", ex); _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = ex.Message, Duration = 1 }); } } /// /// 执行运动 /// /// async void ExecuteExecuteMotion(object parameter) { if (parameter == null) { return; } var values = (object[])parameter; var point = values[0] as RPoint; MotionCommand motionCmd = (MotionCommand)values[1]; if (Robot == null || !Robot.IsConnected) return; try { Robot.Timeout = 6000000; switch (motionCmd) { case MotionCommand.Go: await Robot.GoAsync(point); break; case MotionCommand.Jump: await Robot.JumpAsync(point, 0); break; case MotionCommand.Move: await Robot.MoveAsync(point); break; } Robot.Timeout = 5000; _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = $"{Lang.完成}!", Duration = 0.4 }); } catch (Exception ex) { LogHelper.WriteLogError("机器人点位-执行点位时出错", ex); _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = ex.Message, Duration = 1 }); } } /// /// 示教点位 /// /// async void ExecuteTechPointCommand() { if (Robot == null || !Robot.IsConnected) return; if (SelectedPoint == null) return; try { var curpos = await Robot.GetRobotPosAsync(); SelectedPoint.X_Position = curpos.X; SelectedPoint.Y_Position = curpos.Y; SelectedPoint.Z_Position_Start = curpos.Z; SelectedPoint.U_Position = curpos.U; SelectedPoint.R_Position = curpos.V; _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = $"{Lang.完成}!", Duration = 0.4 }); } catch (Exception ex) { LogHelper.WriteLogError("机器人点位-示教点位时出错", ex); _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = ex.Message, Duration = 1 }); } } void ExecuteLoadedCommand() { if (_systemDatabaseService.GetCurrentUser().userPart == Enums.UserPart.Operator) { IsAllowEdit = false; } else { IsAllowEdit = true; } } /// /// 电机 /// /// private async void ExecuteMotorCommand(string obj) { if (Robot == null || !Robot.IsConnected) return; try { await Robot.MotorAsync(Convert.ToBoolean(obj)); _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = $"{Lang.完成}!", Duration = 0.4 }); } catch (Exception ex) { LogHelper.WriteLogError("机器人点击操作时出错!", ex); _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = ex.Message, Duration = 1 }); } } /// /// 重置 /// private async void ExecuteResetCommand() { if (Robot == null || !Robot.IsConnected) return; try { await Robot.ResetAsync(); _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = $"{Lang.完成}!", Duration = 0.4 }); } catch (Exception ex) { LogHelper.WriteLogError("重置机器人时出错!", ex); _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = ex.Message, Duration = 1 }); } } /// /// 锁定刹车 /// private async void ExecuteSLockCommand() { if (Robot == null || !Robot.IsConnected) return; try { await Robot.SLockAsync(); _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = $"{Lang.完成}!", Duration = 0.4 }); } catch (Exception ex) { LogHelper.WriteLogError("机器人锁定刹车时出错!", ex); _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = ex.Message, Duration = 1 }); } } /// /// 释放刹车 /// private async void ExecutesFreeCommand() { if (Robot == null || !Robot.IsConnected) return; try { await Robot.SFreeAsync(); _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = $"{Lang.完成}!", Duration = 0.4 }); } catch (Exception ex) { LogHelper.WriteLogError("机器人释放刹车时出错!", ex); _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = ex.Message, Duration = 1 }); } } private bool CanExecute { get { // 命令可执行仅当机器人可执行且已选择点位 if (Robot != null && Robot.CanExecute) { return SelectedPointInDataGrid != null; } return false; } } /// /// 点位表切换时 /// void ExecuteSelectionChangedCommand() { switch (SelectedIndex) { case 0: Points = SelectProduct.PickCameraPoints; break; case 1: Points = SelectProduct.PickPoints; break; case 2: Points = SelectProduct.SecPosCameraPoints; break; case 3: Points = SelectProduct.ScrewCameraPoints; break; case 4: Points = SelectProduct.ScrewPoints; break; case 5: Points = SelectProduct.CheckCameraPoints; break; default: break; } } /// /// 增加点位 /// void ExecuteAddPointCommand() { //添加点位 Points.Add(new PlcPoint() { Number = Points.Count + 1, X_Velocity = 100, Y_Velocity = 100, Z_Velocity_Start = 100, Z_Velocity_Stop = 100, U_Velocity = 100, R_Velocity = 100, }); // update commands _MovePointUpCommand?.RaiseCanExecuteChanged(); _MovePointDownCommand?.RaiseCanExecuteChanged(); } /// /// 移除点位 /// void ExecuteDeletePointCommand() { if (SelectedPoint == null) { return; } // 确认删除 if (MessageBox.Show("确认要删除选中的点位吗?", "删除点位", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) { return; } int removedIndex = Points.IndexOf(SelectedPoint); Points.Remove(SelectedPoint); //重新编号 for (int i = 0; i < Points.Count; i++) { Points[i].Number = i + 1; } // adjust selection if (Points.Count > 0) { int newIndex = Math.Min(removedIndex, Points.Count - 1); SelectedPointInDataGrid = Points[newIndex]; } else { SelectedPointInDataGrid = null; } // update commands _MovePointUpCommand?.RaiseCanExecuteChanged(); _MovePointDownCommand?.RaiseCanExecuteChanged(); } private bool CanMovePointUp() { return SelectedPointInDataGrid != null && Points.IndexOf(SelectedPointInDataGrid) > 0; } private bool CanMovePointDown() { return SelectedPointInDataGrid != null && Points.IndexOf(SelectedPointInDataGrid) >= 0 && Points.IndexOf(SelectedPointInDataGrid) < Points.Count - 1; } /// /// 向上移动点位 /// void ExecuteMovePointUpCommand() { if (SelectedPointInDataGrid == null) return; // 确认移动 if (MessageBox.Show("确认将选中点位上移一位吗?", "移动点位", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) { return; } int idx = Points.IndexOf(SelectedPointInDataGrid); if (idx <= 0) return; var item = SelectedPointInDataGrid; Points.Move(idx, idx - 1); // renumber for (int i = 0; i < Points.Count; i++) Points[i].Number = i + 1; SelectedPointInDataGrid = item; _MovePointUpCommand?.RaiseCanExecuteChanged(); _MovePointDownCommand?.RaiseCanExecuteChanged(); } /// /// 向下移动点位 /// void ExecuteMovePointDownCommand() { if (SelectedPointInDataGrid == null) return; // 确认移动 if (MessageBox.Show("确认将选中点位下移一位吗?", "移动点位", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) { return; } int idx = Points.IndexOf(SelectedPointInDataGrid); if (idx < 0 || idx >= Points.Count - 1) return; var item = SelectedPointInDataGrid; Points.Move(idx, idx + 1); // renumber for (int i = 0; i < Points.Count; i++) Points[i].Number = i + 1; SelectedPointInDataGrid = item; _MovePointUpCommand?.RaiseCanExecuteChanged(); _MovePointDownCommand?.RaiseCanExecuteChanged(); } /// /// CAD导入点位 /// async void ExecuteImportCadPointCommand() { try { var view = new DxfView(); //show the dialog var result = await DialogHost.Show(view, "RootDialog", null, null, null); if (result != null) { var cadPoints = view.Points; if (cadPoints != null && cadPoints.Count > 0) { //要导入的开始点编号 int startNumber = view.StartIndex; //弹窗提示用户是否确认要导入从该编号开始的点位,点位数量为cadPoints.Count if (MessageBox.Show($"确认要从点位编号 {startNumber} 开始导入 {cadPoints.Count} 个点位吗?", "导入点位", MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes) { return; } //导入点位 for (int i = 0; i < cadPoints.Count; i++) { //如果点位编号已存在,则更新该点位,否则新增点位,只更新XY坐标 var point = cadPoints[i]; var existingPoint = Points.FirstOrDefault(p => p.Number == startNumber + i); if (existingPoint != null) { existingPoint.X_Position = point.X; existingPoint.Y_Position = point.Y; } else { Points.Add(new PlcPoint() { Number = startNumber + i, X_Position = point.X, Y_Position = point.Y, X_Velocity=100, Y_Velocity=100, Z_Velocity_Start=100, Z_Velocity_Stop=100, U_Velocity=100, R_Velocity=100, }); } } //对所有的点位重新编号,确保编号连续 var sortedPoints = Points.OrderBy(p => p.Number).ToList(); Points.Clear(); for (int i = 0; i < sortedPoints.Count; i++) { sortedPoints[i].Number = i + 1; Points.Add(sortedPoints[i]); } _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = $"{Lang.完成}!", Duration = 0.4 }); } } } catch (Exception ex) { LogHelper.WriteLogError("导入CAD点位时出错!", ex); _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = ex.Message, Duration = 1 }); } } #endregion #region 继承 /// /// 确认导航请求时调用。此方法允许您在导航之前执行一些操作。 /// /// /// public void ConfirmNavigationRequest(NavigationContext navigationContext, Action continuationCallback) { continuationCallback(true); } /// /// 接收导航请求时调用。传入导航参数,包含有关导航目标的信息。 /// /// /// public async void OnNavigatedTo(NavigationContext navigationContext) { try { SelectProduct = navigationContext.Parameters.GetValue("SelectProduct"); SelectedIndex = 0; Points = SelectProduct.PickCameraPoints; if (Robot == null) { Robot = _robotService.GetRobotByNumber(1); } if (Robot != null && Robot.IsConnected) { this.Distance = _configService.GetRobotStepDistance(Robot.Id); Robot.EnterDebugMode = true; } else if (Robot != null) { Robot.EnterDebugMode = true; } } catch (Exception ex) { LogHelper.WriteLogError("机器人点位界面进入时出错!", ex); } } /// /// 是否允许导航到此视图模型。 /// /// /// public bool IsNavigationTarget(NavigationContext navigationContext) { return true; } /// /// 导航离开此视图模型时调用。您可以在此处执行清理操作或保存状态。 /// /// public void OnNavigatedFrom(NavigationContext navigationContext) { //if (Robot != null) //{ // Robot.EnterDebugMode = false; //} } #endregion private bool _IsAllowEdit = false; public bool IsAllowEdit { get { return _IsAllowEdit; } set { SetProperty(ref _IsAllowEdit, value); } } private void LoginChange(Models.User user) { if (user.userPart == Enums.UserPart.Operator) { IsAllowEdit = false; } else { IsAllowEdit = true; } } } }