using Cognex.VisionPro; using Cognex.VisionPro.ToolBlock; using MaterialDesignThemes.Wpf; using MathNet.Numerics.LinearAlgebra; using OpenCvSharp; 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.Drawing; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Web.UI.WebControls; using System.Windows; using System.Windows.Media.Imaging; using Team.FFFeederService; using Team.FFFeederService.Interfaces; using Team.FFFeederService.Models; using TeamAAS_VP; using TeamAAS_VP.Controls; using TeamAAS_VP.Core; using TeamAAS_VP.Enums; using TeamAAS_VP.Events; using TeamAAS_VP.Models; using TeamAAS_VP.Resources.Languages; using TeamAAS_VP.Views.Product; namespace TeamAAS_VP.ViewModels.Product { public class FeederParamsViewModel : BindableBase { IRegionManager _regionManager; IEventAggregator _eventAggregator; IContainerProvider _container; IDialogService _dialogService; ProductsViewModel productsViewModel; CancellationTokenSource TokenSource; CancellationTokenSource AutoFindVirCTS; #region 属性 private ProductModel _SelectProduct; /// /// 选中的产品 /// public ProductModel SelectProduct { get { return _SelectProduct; } set { SetProperty(ref _SelectProduct, value); } } private ProcedureModel _SelectProcedure; /// /// 选中的流程 /// public ProcedureModel SelectProcedure { get { return _SelectProcedure; } set { SetProperty(ref _SelectProcedure, value); } } private int _SelectFeederFunctionIndex; public int SelectFeederFunctionIndex { get { return _SelectFeederFunctionIndex; } set { SetProperty(ref _SelectFeederFunctionIndex, value); if (value >= 0 && value <= 25) { SelectFeederFunction = (VibrationFunction)value; } else { SelectFeederFunction = VibrationFunction.Delay; } } } private VibrationFunction _SelectFeederFunction; /// /// 选中的feeder振动功能码 /// public VibrationFunction SelectFeederFunction { get { return _SelectFeederFunction; } set { SetProperty(ref _SelectFeederFunction, value); } } private int _SelectStockFeederFunctionIndex; public int SelectStockFeederFunctionIndex { get { return _SelectStockFeederFunctionIndex; } set { SetProperty(ref _SelectStockFeederFunctionIndex, value); if (value >= 0 && value <= 25) { SelectStockFeederFunction = (VibrationFunction)value; } else { SelectStockFeederFunction = VibrationFunction.Delay; } } } private VibrationFunction _SelectStockFunction; /// /// 选中的feeder料仓功能码 /// public VibrationFunction SelectStockFunction { get { return _SelectStockFunction; } set { SetProperty(ref _SelectStockFunction, value); } } private VibrationFunction _SelectStockFeederFunction; /// /// 选中的feeder料仓振动盘功能码 /// public VibrationFunction SelectStockFeederFunction { get { return _SelectStockFeederFunction; } set { SetProperty(ref _SelectStockFeederFunction, value); } } public Management management { get; set; } public FeederService feederService { get; set; } private IVoiceCoilMotorFeeder _Feeder; public IVoiceCoilMotorFeeder Feeder { get { return _Feeder; } set { SetProperty(ref _Feeder, value); } } private int _SelectActionIndex = -1; /// /// Feeder动作索引 /// public int SelectActionIndex { get { return _SelectActionIndex; } set { SetProperty(ref _SelectActionIndex, value); if (value >= 0 && SelectProcedure.FeederFindFrequency != null && SelectProcedure.FeederFindFrequency.FeederFindFrequency != null) { SelectedActionParam = SelectProcedure.FeederFindFrequency.FeederFindFrequency.FirstOrDefault(f => f.ActionIndex == value); if (SelectedActionParam.AmplitudeMax == SelectedActionParam.AmplitudeMin || SelectedActionParam.FrequencyMax == SelectedActionParam.FrequencyMin) { AutoAdjustmentParameter findVirTask = new AutoAdjustmentParameter(Feeder, SelectedActionParam.ActionIndex, ExecuteVisualPhoto); var defultpar = findVirTask.detector.GetLogicParameters(); SelectedActionParam.AmplitudeMax = defultpar.u16MaxAmp; SelectedActionParam.AmplitudeMin = defultpar.u16MinAmp; SelectedActionParam.FrequencyMax = defultpar.u16MaxFre; SelectedActionParam.FrequencyMin = defultpar.u16MinFre; SelectedActionParam.Duration= defultpar.u16Tim; findVirTask.Dispose(); } } else { SelectedActionParam = null; } } } private ActionParamsExtModel _SelectedActionParam; public ActionParamsExtModel SelectedActionParam { get { return _SelectedActionParam; } set { SetProperty(ref _SelectedActionParam, value); } } private bool _InExecutionFindVibP; /// /// 正在执行自动寻找振动参数 /// public bool InExecutionFindVibP { get { return _InExecutionFindVibP; } set { SetProperty(ref _InExecutionFindVibP, value); } } private BitmapSource _CameraImage; public BitmapSource CameraImage { get { return _CameraImage; } set { SetProperty(ref _CameraImage, value); } } private bool _FeederDirectionInverse; public bool FeederDirectionInverse { get { return _FeederDirectionInverse; } set { SetProperty(ref _FeederDirectionInverse, value); } } private SingleActionParam _SingleActionParam=new SingleActionParam(); /// /// 自动调频时的动作参数 /// public SingleActionParam SingleActionParam { get { return _SingleActionParam; } set { SetProperty(ref _SingleActionParam, value); } } private string _StateMesg; public string StateMesg { get { return _StateMesg; } set { SetProperty(ref _StateMesg, value); } } #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 _AddFunctionCommand; public DelegateCommand AddFunctionCommand => _AddFunctionCommand ?? (_AddFunctionCommand = new DelegateCommand(ExecuteAddFunctionCommand)); private DelegateCommand _RemoveFunctionCommand; public DelegateCommand RemoveFunctionCommand => _RemoveFunctionCommand ?? (_RemoveFunctionCommand = new DelegateCommand(ExecuteRemoveFunctionCommand)); private DelegateCommand _LoadedCommand; public DelegateCommand LoadedCommand => _LoadedCommand ?? (_LoadedCommand = new DelegateCommand(ExecuteLoadedCommand)); private DelegateCommand _AddStockFunctionCommand; public DelegateCommand AddStockFunctionCommand => _AddStockFunctionCommand ?? (_AddStockFunctionCommand = new DelegateCommand(ExecuteAddStockFunctionCommand)); private DelegateCommand _RemoveStockFunctionCommand; public DelegateCommand RemoveStockFunctionCommand => _RemoveStockFunctionCommand ?? (_RemoveStockFunctionCommand = new DelegateCommand(ExecuteRemoveStockFunctionCommand)); private DelegateCommand _AddStockFeederFunctionCommand; public DelegateCommand AddStockFeederFunctionCommand => _AddStockFeederFunctionCommand ?? (_AddStockFeederFunctionCommand = new DelegateCommand(ExecuteAddStockFeederFunctionCommand)); private DelegateCommand _RemoveStockFeederFunctionCommand; public DelegateCommand RemoveStockFeederFunctionCommand => _RemoveStockFeederFunctionCommand ?? (_RemoveStockFeederFunctionCommand = new DelegateCommand(ExecuteRemoveStockFeederFunctionCommand)); private DelegateCommand _SettingStockCommand; public DelegateCommand SettingStockCommand => _SettingStockCommand ?? (_SettingStockCommand = new DelegateCommand(ExecuteSettingStockCommand)); private DelegateCommand _RunCommandWorks; public DelegateCommand RunCommandWorks => _RunCommandWorks ?? (_RunCommandWorks = new DelegateCommand(ExecuteRunCommandWorks).ObservesCanExecute(() => IsCanExecute)); private DelegateCommand _AutoFindVibrationParamsCommand; public DelegateCommand AutoFindVibrationParamsCommand => _AutoFindVibrationParamsCommand ?? (_AutoFindVibrationParamsCommand = new DelegateCommand(ExecuteAutoFindVibrationParamsCommand, CanExecuteAutoFindVibrationParamsCommand).ObservesProperty(() => InExecutionFindVibP)); private DelegateCommand _StopAutoFindCommand; public DelegateCommand StopAutoFindCommand => _StopAutoFindCommand ?? (_StopAutoFindCommand = new DelegateCommand(ExecuteStopAutoFindCommand, CanExecuteStopAutoFindCommand).ObservesProperty(() => InExecutionFindVibP)); #endregion #region 事件 #endregion public FeederParamsViewModel(IRegionManager regionManager, IEventAggregator ea, IContainerProvider container, IDialogService dialogService) { _regionManager = regionManager; _eventAggregator = ea; _container = container; _dialogService = dialogService; //订阅权限登录事件 _eventAggregator.GetEvent().Subscribe(LoginChange); management = _container.Resolve(); productsViewModel = _container.Resolve(); SelectProduct = productsViewModel.SelectProduct; SelectProcedure = _container.Resolve().SelectProcedure; } #region 方法 /// /// 下一步 /// async void ExecuteNextCommand() { _regionManager.RequestNavigate("ProductRegionContext", "ProcedureVisionOutput"); try { if (Feeder != null && Feeder.IsConnected) { foreach (var item in SelectProcedure.FeederWorks.FeederWorkList) { if (item.Function == VibrationFunction.Delay) continue; var paramCollection = await Feeder.GetShakeGroupValueAsync((int)item.Function); item.SingleAction = paramCollection; } foreach (var item in SelectProcedure.FeederStockWorks.FeederWorkList) { if (item.Function == VibrationFunction.Delay) continue; var paramCollection = await Feeder.GetShakeGroupValueAsync((int)item.Function); item.SingleAction = paramCollection; } } } catch (Exception ex) { LogHelper.WriteLogError("Feeder 参数界面点击下一步时出错!", ex); MessageBox.Show(ex.Message); } } /// /// 上一步 /// void ExecuteBackCommand() { if (SelectProcedure.VisionModel == Enums.VisionModel.Simple) { _regionManager.RequestNavigate("ProductRegionContext", "SimpleProcedure"); } else { _regionManager.RequestNavigate("ProductRegionContext", "AdvancedProcedure"); } } /// /// 增加振动盘振动任务 /// async void ExecuteAddFunctionCommand() { try { if (SelectProcedure.FeederWorks == null) { SelectProcedure.FeederWorks = new FeederWorks(); } if (SelectFeederFunction == VibrationFunction.Delay) { var view = new AddProduct() { Title = $"{Lang.添加动作}:", Item = $"{Lang.持续时长}(ms)" }; //show the dialog var result = await DialogHost.Show(view, "RootDialog", null, null, null); if (result != null && !string.IsNullOrEmpty(result.ToString()) && int.TryParse(result.ToString(), out int time)) { SelectProcedure.FeederWorks.Add(new FeederWork() { Step = SelectProcedure.FeederWorks.Count, Function = SelectFeederFunction, Duration = time }); } } else { var view = new AddProduct() { Title = $"{Lang.添加动作}:", Item = $"{Lang.持续时长}(ms)" }; //show the dialog var result = await DialogHost.Show(view, "RootDialog", null, null, null); if (result != null && !string.IsNullOrEmpty(result.ToString()) && int.TryParse(result.ToString(), out int time)) { if (Feeder != null && Feeder.IsConnected) { var paramCollection = await Feeder.GetShakeGroupValueAsync((int)SelectFeederFunction); SelectProcedure.FeederWorks.Add(new FeederWork() { Step = SelectProcedure.FeederWorks.Count, Function = SelectFeederFunction, Duration = time, SingleAction = paramCollection }); } else { SelectProcedure.FeederWorks.Add(new FeederWork() { Step = SelectProcedure.FeederWorks.Count, Function = SelectFeederFunction, Duration = time }); } } } } catch (Exception ex) { LogHelper.WriteLogError("Feeder 参数界面增加振动盘任务时出错!", ex); MessageBox.Show(ex.Message); } } /// /// 移除振动盘振动任务 /// /// void ExecuteRemoveFunctionCommand(object index) { try { if (SelectProcedure.FeederWorks == null || SelectProcedure.FeederWorks.FeederWorkList == null) { return; } if ((int)index < 0) return; SelectProcedure.FeederWorks.FeederWorkList.RemoveAt((int)index); } catch (Exception ex) { LogHelper.WriteLogError("Feeder 参数界面移除振动盘任务时出错!", ex); MessageBox.Show(ex.Message); } } /// /// 增加料仓振动任务 /// async void ExecuteAddStockFunctionCommand() { try { if (SelectProcedure.FeederStockWorks == null) { SelectProcedure.FeederStockWorks = new FeederStockWorks(); SelectProcedure.FeederStockWorks.FeederStockWorkList = new ObservableCollection(); SelectProcedure.FeederStockWorks.FeederWorkList = new ObservableCollection(); } if (SelectProcedure.FeederStockWorks.FeederStockWorkList == null) { SelectProcedure.FeederStockWorks.FeederStockWorkList = new ObservableCollection(); } if (SelectProcedure.FeederStockWorks.FeederWorkList == null) { SelectProcedure.FeederStockWorks.FeederWorkList = new ObservableCollection(); } var view = new AddProduct() { Title = $"{Lang.添加动作}:", Item = $"{Lang.持续时长}(ms)" }; //show the dialog var result = await DialogHost.Show(view, "RootDialog", null, null, null); if (result != null && !string.IsNullOrEmpty(result.ToString()) && int.TryParse(result.ToString(), out int time)) { SelectProcedure.FeederStockWorks.FeederStockWorkList.Add(new FeederStockWork() { Step = SelectProcedure.FeederStockWorks.FeederStockWorkList.Count, Function = SelectStockFeederFunction, Duration = time }); } } catch (Exception ex) { LogHelper.WriteLogError("Feeder 参数界面增加料仓任务时出错!", ex); MessageBox.Show(ex.Message); } } /// /// 移除料仓振动任务 /// /// void ExecuteRemoveStockFunctionCommand(object index) { try { if (SelectProcedure.FeederStockWorks == null || SelectProcedure.FeederStockWorks.FeederStockWorkList == null) { return; } if ((int)index < 0) return; SelectProcedure.FeederStockWorks.FeederStockWorkList.RemoveAt((int)index); } catch (Exception ex) { LogHelper.WriteLogError("Feeder 参数界面移除料仓任务时出错!", ex); MessageBox.Show(ex.Message); } } /// /// 增加料仓振动时的振动盘振动任务 /// async void ExecuteAddStockFeederFunctionCommand() { try { if (SelectProcedure.FeederStockWorks == null) { SelectProcedure.FeederStockWorks = new FeederStockWorks(); SelectProcedure.FeederStockWorks.FeederStockWorkList = new ObservableCollection(); SelectProcedure.FeederStockWorks.FeederWorkList = new ObservableCollection(); } if (SelectProcedure.FeederStockWorks.FeederStockWorkList == null) { SelectProcedure.FeederStockWorks.FeederStockWorkList = new ObservableCollection(); } if (SelectProcedure.FeederStockWorks.FeederWorkList == null) { SelectProcedure.FeederStockWorks.FeederWorkList = new ObservableCollection(); } if (SelectStockFeederFunction == VibrationFunction.Delay) { var view = new AddProduct() { Title = $"{Lang.添加动作}:", Item = $"{Lang.持续时长}(ms)" }; //show the dialog var result = await DialogHost.Show(view, "RootDialog", null, null, null); if (result != null && !string.IsNullOrEmpty(result.ToString()) && int.TryParse(result.ToString(), out int time)) { SelectProcedure.FeederStockWorks.FeederWorkList.Add(new FeederWork() { Step = SelectProcedure.FeederStockWorks.FeederWorkList.Count, Function = SelectStockFeederFunction, Duration = time }); } } else { var view = new AddProduct() { Title = $"{Lang.添加动作}:", Item = $"{Lang.持续时长}(ms)" }; //show the dialog var result = await DialogHost.Show(view, "RootDialog", null, null, null); if (result != null && !string.IsNullOrEmpty(result.ToString()) && int.TryParse(result.ToString(), out int time)) { if (Feeder != null && Feeder.IsConnected) { var paramCollection = await Feeder.GetShakeGroupValueAsync((int)SelectStockFeederFunction); SelectProcedure.FeederStockWorks.FeederWorkList.Add(new FeederWork() { Step = SelectProcedure.FeederStockWorks.FeederWorkList.Count, Function = SelectStockFeederFunction, Duration = time, SingleAction = paramCollection }); } else { SelectProcedure.FeederStockWorks.FeederWorkList.Add(new FeederWork() { Step = SelectProcedure.FeederStockWorks.FeederWorkList.Count, Function = SelectStockFeederFunction, Duration = time }); } } } } catch (Exception ex) { LogHelper.WriteLogError("Feeder 参数界面增加料仓动作时的振动盘任务时出错!", ex); MessageBox.Show(ex.Message); } } /// /// 移除料仓振动任务 /// /// void ExecuteRemoveStockFeederFunctionCommand(object index) { try { if (SelectProcedure.FeederStockWorks == null || SelectProcedure.FeederStockWorks.FeederWorkList == null) { return; } if ((int)index < 0) return; SelectProcedure.FeederStockWorks.FeederWorkList.RemoveAt((int)index); } catch (Exception ex) { LogHelper.WriteLogError("Feeder 参数界面移除料仓动作时的振动盘任务时出错!", ex); MessageBox.Show(ex.Message); } } /// /// 料仓出料时机参数设定 /// void ExecuteSettingStockCommand() { try { _dialogService.Show("FeederBlobParams", rst => { //对话框关闭之后的回调函数,可以在这解析结果。 ButtonResult result1 = rst.Result; if (result1 == ButtonResult.OK) { SelectProcedure.MinArea = rst.Parameters.GetValue("MinArea"); _eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = $"{Lang.完成}!", Duration = 1 }); } }); } catch (Exception ex) { LogHelper.WriteLogError("Feeder 参数界面打开FeederBlob参数界面时出错!", ex); MessageBox.Show(ex.Message); } } async void ExecuteLoadedCommand() { if (_container.Resolve().CurrentUser.userPart == Enums.UserPart.Operator) { IsAllowEdit = false; } else { IsAllowEdit = true; } try { productsViewModel = _container.Resolve(); SelectProduct = productsViewModel.SelectProduct; SelectProcedure = _container.Resolve().SelectProcedure; feederService = management.FeederService; Feeder = feederService.GetFeeder(SelectProcedure.FeederId); if (Feeder != null && Feeder.IsConnected) { if (SelectProcedure.FeederWorks != null && SelectProcedure.FeederWorks.FeederWorkList != null) { foreach (var item in SelectProcedure.FeederWorks.FeederWorkList) { if (item.Function == VibrationFunction.Delay) continue; if (item.SingleAction == null) continue; await Feeder.SetShakeParametersAsync((int)item.Function, item.SingleAction); } } if (SelectProcedure.FeederStockWorks != null && SelectProcedure.FeederStockWorks.FeederWorkList != null) { foreach (var item in SelectProcedure.FeederStockWorks.FeederWorkList) { if (item.Function == VibrationFunction.Delay) continue; if (item.SingleAction == null) continue; await Feeder.SetShakeParametersAsync((int)item.Function, item.SingleAction); } } } if (SelectProcedure.FeederFindFrequency == null) { SelectProcedure.FeederFindFrequency = new FeederFrequencyModel(11); } if (SelectActionIndex < 0) { SelectActionIndex = 0; } if (SelectedActionParam.AmplitudeMax == SelectedActionParam.AmplitudeMin || SelectedActionParam.FrequencyMax == SelectedActionParam.FrequencyMin) { AutoAdjustmentParameter findVirTask = new AutoAdjustmentParameter(Feeder, SelectedActionParam.ActionIndex, ExecuteVisualPhoto); var defultpar = findVirTask.detector.GetLogicParameters(); SelectedActionParam.AmplitudeMax = defultpar.u16MaxAmp; SelectedActionParam.AmplitudeMin = defultpar.u16MinAmp; SelectedActionParam.FrequencyMax = defultpar.u16MaxFre; SelectedActionParam.FrequencyMin = defultpar.u16MinFre; SelectedActionParam.Duration = defultpar.u16Tim; findVirTask.Dispose(); } if (SingleActionParam.Motor1 == null) { SingleActionParam.Motor1 = new VoiceMotorParam(); } if (SingleActionParam.Motor2 == null) { SingleActionParam.Motor2 = new VoiceMotorParam(); } if (SingleActionParam.Motor3 == null) { SingleActionParam.Motor3 = new VoiceMotorParam(); } if (SingleActionParam.Motor4 == null) { SingleActionParam.Motor4 = new VoiceMotorParam(); } } catch (Exception ex) { LogHelper.WriteLogError("Feeder 参数界面打开FeederBlob参数界面时出错!", ex); MessageBox.Show(ex.Message); } } private bool _IsCanExecute = true; public bool IsCanExecute { get { return _IsCanExecute; } set { SetProperty(ref _IsCanExecute, value); } } async void ExecuteRunCommandWorks(string index) { try { IsCanExecute = false; int num = int.Parse(index); if (num == 0) { TokenSource = new CancellationTokenSource(); var view = new WaitingPage(); //show the dialog DialogHost.Show(view, "RootDialog", null, ExtendedClosingEventHandler, ExtendedClosedEventHandler); await management.ExecuteFeederWorks(Feeder, SelectProcedure.FeederWorks, TokenSource.Token, false); if (DialogHost.IsDialogOpen("RootDialog")) { TokenSource = null; DialogHost.Close("RootDialog"); } TokenSource = null; } else if (num == 1) { TokenSource = new CancellationTokenSource(); var view = new WaitingPage(); //show the dialog DialogHost.Show(view, "RootDialog", null, ExtendedClosingEventHandler, ExtendedClosedEventHandler); await management.ExecuteFeederStockWorks(Feeder, SelectProcedure.FeederStockWorks, TokenSource.Token, false); if (DialogHost.IsDialogOpen("RootDialog")) { TokenSource = null; DialogHost.Close("RootDialog"); } TokenSource = null; } } catch (Exception ex) { LogHelper.WriteLogError("Feeder 参数界面执行Feeder运动任务时出错时出错!", ex); MessageBox.Show(ex.Message); } finally { IsCanExecute = true; } } private void ExtendedClosingEventHandler(object sender, DialogClosingEventArgs eventArgs) { if (TokenSource != null) { TokenSource.Cancel(); } } private void ExtendedClosedEventHandler(object sender, DialogClosedEventArgs eventArgs) { } /// /// 自动寻频 /// async void ExecuteAutoFindVibrationParamsCommand() { try { AutoFindVirCTS = new CancellationTokenSource(); InExecutionFindVibP = true; var calib = management.DeviceConfig.Calibrations.FirstOrDefault(f => f.Id == SelectProcedure.CalibrationId); if (SelectedActionParam == null) { SelectedActionParam = new ActionParamsExtModel(); } AutoAdjustmentParameter findVirTask = new AutoAdjustmentParameter(Feeder, SelectedActionParam.ActionIndex, ExecuteVisualPhoto); findVirTask.OnVibrationParamChanged += (amp) => { Application.Current.Dispatcher.Invoke(() => { SingleActionParam.Motor1.Amplitude = amp.Motor1.Amplitude; SingleActionParam.Motor1.Frequency = amp.Motor1.Frequency; SingleActionParam.Motor1.Phase = amp.Motor1.Phase; SingleActionParam.Motor1.WaveShape = amp.Motor1.WaveShape; SingleActionParam.Motor2.Amplitude = amp.Motor2.Amplitude; SingleActionParam.Motor2.Frequency = amp.Motor3.Frequency; SingleActionParam.Motor2.Phase = amp.Motor2.Phase; SingleActionParam.Motor2.WaveShape = amp.Motor2.WaveShape; SingleActionParam.Motor3.Amplitude = amp.Motor3.Amplitude; SingleActionParam.Motor3.Frequency = amp.Motor3.Frequency; SingleActionParam.Motor3.Phase = amp.Motor3.Phase; SingleActionParam.Motor3.WaveShape = amp.Motor3.WaveShape; SingleActionParam.Motor4.Amplitude = amp.Motor4.Amplitude; SingleActionParam.Motor4.Frequency = amp.Motor4.Frequency; SingleActionParam.Motor4.Phase = amp.Motor4.Phase; SingleActionParam.Motor4.WaveShape = amp.Motor4.WaveShape; SingleActionParam.DurationValue = amp.DurationValue; }); }; findVirTask.detector.SetLogicParameters((ushort)SelectedActionParam.AmplitudeMin, (ushort)SelectedActionParam.AmplitudeMax, (ushort)SelectedActionParam.FrequencyMin, (ushort)SelectedActionParam.FrequencyMax, (ushort)SelectedActionParam.Duration); await findVirTask.Execute(SelectedActionParam.AmplitudeMax, SelectedActionParam.AmplitudeMin, SelectedActionParam.FrequencyMax, SelectedActionParam.FrequencyMin, SelectedActionParam.Duration, AutoFindVirCTS.Token, res => { //0 :失败 1:运行中 3:完成调频 6:验证结束 if (res == 0) { App.Current.Dispatcher.Invoke(() => { StateMesg = "寻频失败"; }); AutoFindVirCTS.Cancel(); } else if (res == 1) { App.Current.Dispatcher.Invoke(() => { StateMesg = "寻频中..."; }); } //动作结束 else if (res == 2) { App.Current.Dispatcher.Invoke(() => { StateMesg = "移动物料到起始位置"; }); //if (MessageBox.Show( "请将物料手动移动回原位,将进行下一次调频。", "AAS", MessageBoxButton.YesNo, MessageBoxImage.Asterisk) == MessageBoxResult.Yes) //{ // //findVirTask.SetState(1); //} //else //{ // //AutoFindVirCTS.Cancel(); //} } //完成调频,进行测试效果 else if (res == 3) { App.Current.Dispatcher.Invoke(() => { StateMesg = "验证进行中"; }); if (MessageBox.Show("请使用更多物料去验证动作振动效果。", "AAS", MessageBoxButton.YesNo, MessageBoxImage.Asterisk) == MessageBoxResult.Yes) { findVirTask.SetState(2); } else { App.Current.Dispatcher.Invoke(() => { StateMesg = "停止"; }); findVirTask.SetState(0); AutoFindVirCTS.Cancel(); } } //验证结束。 else if (res == 6) { App.Current.Dispatcher.Invoke(() => { StateMesg = "验证结束"; }); if (MessageBox.Show("是否重复震动验证?", "AAS", MessageBoxButton.YesNo, MessageBoxImage.Asterisk) == MessageBoxResult.Yes) { App.Current.Dispatcher.Invoke(() => { StateMesg = "重复验证"; }); findVirTask.SetState(2); } else { if (MessageBox.Show("请确认当前振动效果是否正确?", "AAS", MessageBoxButton.YesNo, MessageBoxImage.Asterisk) == MessageBoxResult.Yes) { App.Current.Dispatcher.Invoke(() => { StateMesg = "验证完成"; }); findVirTask.SetState(3); AutoFindVirCTS.Cancel(); } else { App.Current.Dispatcher.Invoke(() => { StateMesg = "继续调频"; }); findVirTask.SetState(1); //AutoFindVirCTS.Cancel(); } } } }); findVirTask.Dispose(); Feeder.CloseLight(); } catch (Exception ex) { LogHelper.WriteLogError("Feeder 参数界面执行自动寻找振动参数时出错!", ex); } finally { InExecutionFindVibP = false; } } bool CanExecuteAutoFindVibrationParamsCommand() { return !InExecutionFindVibP; } /// /// 停止自动寻找振动参数 /// void ExecuteStopAutoFindCommand() { if (AutoFindVirCTS != null) { AutoFindVirCTS.Cancel(); } } bool CanExecuteStopAutoFindCommand() { return InExecutionFindVibP; } /// /// 执行相机拍照(拍摄Feeder,自动寻频功能),并返回拍照结果 /// /// private Tuple ExecuteVisualPhoto() { try { if (!Feeder.QueryLightState()) { Feeder.OpenLight(); Thread.Sleep(100); } var cam = management.CameraService.GetCamera(SelectProcedure.CameraId); if (!SelectProcedure.ToolBlock.Tools.Contains("CogToolBlock-FeederCalib")) { ShowMsg("视觉工具组不存在名称为:'CogToolBlock-FeederCalib'的ToolBlock"); return new Tuple(false, 0, 0); } var tb = SelectProcedure.ToolBlock.Tools["CogToolBlock-FeederCalib"] as CogToolBlock; var image = cam.Grab(); tb.Inputs["InputImage"].Value = image; tb.Run(); Mat mat = ICogImageConvertMat(image); if (tb.RunStatus.Result != CogToolResultConstants.Accept) { CameraImage = OpenCvSharp.WpfExtensions.BitmapSourceConverter.ToBitmapSource(mat); mat.Dispose(); ShowMsg($"CogToolBlock-FeederCalib运行出错!error:{tb.RunStatus.Message}"); LogHelper.WriteLogInfo($"CogToolBlock-FeederCalib运行出错!error:{tb.RunStatus.Message}"); return new Tuple(false, 0, 0); } bool found = (bool)tb.Outputs["Found"].Value; if (!found) { CameraImage = OpenCvSharp.WpfExtensions.BitmapSourceConverter.ToBitmapSource(mat); mat.Dispose(); ShowMsg($"视觉工具运行失败!"); return new Tuple(false, 0, 0); } CogRectangleAffine Rectangle = tb.Outputs["Rectang"].Value as CogRectangleAffine; double MassX = (double)tb.Outputs["MassX"].Value; double MassY = (double)tb.Outputs["MassY"].Value; //创建旋转矩形对象 OpenCvSharp.RotatedRect rotatedRect = new OpenCvSharp.RotatedRect(new OpenCvSharp.Point2f((float)Rectangle.CenterX, (float)Rectangle.CenterY), new OpenCvSharp.Size2f((float)Rectangle.SideXLength, (float)Rectangle.SideYLength), (float)ToolCoord.RadToAngle(Rectangle.Rotation)); // 获取矩形的四个顶点 Point2f[] vertices = rotatedRect.Points(); //[1]━━━━━━━━━━[2] // ┃ ┃ // ┃ ┃ // ┃ ┃ //[0]━━━━━━━━━━[3] // 绘制旋转矩形 Cv2.DrawContours(mat, new[] { Array.ConvertAll(vertices, v => new OpenCvSharp.Point((int)v.X, (int)v.Y)) }, 0, Scalar.Blue, 2); // 绘制标记点 Cv2.DrawMarker(mat, new OpenCvSharp.Point(MassX, MassY), new Scalar(255, 0, 0), MarkerTypes.Cross, 40, 5); //绘制Feeder坐标系 if (!SelectProcedure.FeederFindFrequency.FeederDirectionInverse) { Cv2.Line(mat, (int)vertices[2].X, (int)vertices[2].Y, (int)vertices[1].X, (int)vertices[1].Y, Scalar.Red, 5); Cv2.Line(mat, (int)vertices[2].X, (int)vertices[2].Y, (int)vertices[3].X, (int)vertices[3].Y, Scalar.Green, 5); } else { Cv2.Line(mat, (int)vertices[0].X, (int)vertices[0].Y, (int)vertices[3].X, (int)vertices[3].Y, Scalar.Red, 5); Cv2.Line(mat, (int)vertices[0].X, (int)vertices[0].Y, (int)vertices[1].X, (int)vertices[1].Y, Scalar.Green, 5); } App.Current.Dispatcher.Invoke(() => { CameraImage = OpenCvSharp.WpfExtensions.BitmapSourceConverter.ToBitmapSource(mat); }); mat.Dispose(); var calib = management.DeviceConfig.Calibrations.FirstOrDefault(f => f.Id == SelectProcedure.CalibrationId); Point2f p0 = new Point2f((float)(MassX * calib.PixelScaleX), (float)(MassY * calib.PixelScaleY)); //矩形顶点坐标(mm) Point2f p1 = new Point2f((float)(vertices[0].X * calib.PixelScaleX + 10), (float)(vertices[0].Y * calib.PixelScaleY)); Point2f p2 = new Point2f((float)(vertices[1].X * calib.PixelScaleX + 10), (float)(vertices[1].Y * calib.PixelScaleY)); Point2f p3 = new Point2f((float)(vertices[2].X * calib.PixelScaleX + 10), (float)(vertices[2].Y * calib.PixelScaleY)); Point2f p4 = new Point2f((float)(vertices[3].X * calib.PixelScaleX + 10), (float)(vertices[3].Y * calib.PixelScaleY)); //创建Local坐标系 CoordinateTransformer local = new CoordinateTransformer(p3.X, p3.Y, p2.X, p2.Y, p4.X, p4.Y); if (SelectProcedure.FeederFindFrequency.FeederDirectionInverse) { local = new CoordinateTransformer(p1.X, p1.Y, p4.X, p4.Y, p2.X, p2.Y); } //转换到Local坐标系 Vector localP = local.ToNewCoord(p0.X, p0.Y); return new Tuple(found, (float)localP[0], (float)localP[1]); } catch (Exception ex) { LogHelper.WriteLogError("执行相机拍照(拍摄Feeder,自动寻频功能)时出错!", ex); return new Tuple(false, 0, 0); } } private Mat ICogImageConvertMat(ICogImage image) { var im = image.ToBitmap(); Mat im1 = OpenCvSharp.Extensions.BitmapConverter.ToMat(im); im.Dispose(); return im1; } #endregion private void ShowMsg(string msg, double duration = 1) { //_eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = msg, Duration = duration }); } 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; } } } }