using Aitex.Core.Util; using LiveCharts.Wpf; using MECF.Framework.Common.Beckhoff.Station; using MECF.Framework.Common.CommonData.PUF; using MECF.Framework.Common.DataCenter; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Layout; using MECF.Framework.Common.ProcessCell; using MECF.Framework.Common.Reservior; using MECF.Framework.Common.Utilities; using CyberX8_Core; using CyberX8_Themes.UserControls; using Prism.Mvvm; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Timers; using System.Windows.Threading; using System.Windows; using System.Windows.Markup; namespace CyberX8_MainPages.ViewModels { public class ProcessChamberViewModel : BindableBase { #region 常量 private const string CURRENT_STATION = "CurrentStation"; private const string MOTION_DATA = "MotionData"; /// /// Transporter盒子的宽度85 /// private const int TRANSPORTER_BOX_LENGTH = 85; /// /// Loader Buffer元素宽度的一半(12/2) /// private const int LOADER_BUFFER_HALF_LENGTH = 6; /// /// Transporter中线最高位置到Cell之间的距离 /// private const int VERTICAL_DISTANCE = 115; #endregion #region 内部变量 private ProcessLayout _processLayout; /// /// Loader Gantry运动数据 /// private CommandMotionData _loaderGantryMotionData; /// /// Loader Elevator运动数据 /// private CommandMotionData _loaderElevatorMotionData; /// /// Loader Transporter Gantry当前位置 /// private double _loaderTransporterGantryPosition; /// /// Loader transporter Elevator当前位置 /// private double _loaderTransporterElevatorPosition; /// /// Process Gantry运动数据 /// private CommandMotionData _processGantryMotionData; /// /// Process Elevator运动数据 /// private CommandMotionData _processElevatorMotionData; /// /// Process transporter Gantry当前位置 /// private double _processTransporterGantryPosition; /// /// Process transporter Elevator当前位置 /// private double _processTransporterElevatorPosition; /// /// UI水平距离 /// private int _transporterLayoutHorizontalDistance; /// /// ui 水平比例 /// private double _horizontalRatio; /// /// ui垂直比例 /// private double _verticalRatio; /// /// Loader UI的位置 /// private int _loaderPosition; /// /// Cell 工位最左侧的位置 /// private double _stationMin; /// /// Process与Loader偏差距离 /// private int _biasDistanceBetweenLoaderAndProcess; /// /// RT查询key集合 /// private List _rtDataKeys = new List(); /// /// rt查询key数值字典 /// private Dictionary _rtDataValueDic = new Dictionary(); /// /// 定时器 /// private DispatcherTimer _timer; /// /// Process控件是否加载 /// private bool _processControlLoaded; #endregion #region 属性 public ProcessLayout ProcessLayout { get { return _processLayout; } set { SetProperty(ref _processLayout, value); } } public CommandMotionData LoaderGantryMotionData { get { return _loaderGantryMotionData; } set { SetProperty(ref _loaderGantryMotionData, value); } } public CommandMotionData LoaderElevatorMotionData { get { return _loaderElevatorMotionData; } set { SetProperty(ref _loaderElevatorMotionData, value); } } public double LoaderTransporterGantryPosition { get { return _loaderTransporterGantryPosition; } set { SetProperty(ref _loaderTransporterGantryPosition, value); } } public double LoaderTransporterElevatorPosition { get { return _loaderTransporterElevatorPosition; } set { SetProperty(ref _loaderTransporterElevatorPosition, value); } } public CommandMotionData ProcessGantryMotionData { get { return _processGantryMotionData; } set { SetProperty(ref _processGantryMotionData, value); } } public CommandMotionData ProcessElevatorMotionData { get { return _processElevatorMotionData; } set { SetProperty(ref _processElevatorMotionData, value); } } public double ProcessTransporterGantryPosition { get { return _processTransporterGantryPosition; } set { SetProperty(ref _processTransporterGantryPosition, value); } } public double ProcessTransporterElevatorPosition { get { return _processTransporterElevatorPosition; } set { SetProperty(ref _processTransporterElevatorPosition, value); } } public bool ProcessControlLoaded { get { return _processControlLoaded; } set { SetProperty(ref _processControlLoaded, value); } } #endregion public ProcessChamberViewModel() { } /// /// 加载数据 /// public void LoadData(object obj) { if (obj==null) { return; } ProcessControlLoaded = true; _transporterLayoutHorizontalDistance=(int) QueryDataClient.Instance.Service.GetConfig("Transporter.TransporterLayoutHorizontalDistance"); _loaderPosition = (int)QueryDataClient.Instance.Service.GetConfig("Transporter.TransporterLayoutLoaderPosition"); _biasDistanceBetweenLoaderAndProcess= (int)QueryDataClient.Instance.Service.GetConfig("Transporter.BiasDistanceBetweenLoaderAndProcess"); _rtDataKeys.Clear(); _rtDataKeys.Add($"Station.{ModuleName.Transporter2}.Gantry"); _rtDataKeys.Add($"Station.{ModuleName.Transporter1}.Gantry"); _rtDataKeys.Add($"Station.{ModuleName.Transporter2}.Elevator"); _rtDataKeys.Add($"Station.{ModuleName.Transporter1}.Elevator"); _rtDataValueDic = QueryDataClient.Instance.Service.PollData(_rtDataKeys); if(_rtDataValueDic!=null) { BeckhoffStationAxis loaderTransporterAxis = CommonFunction.GetValue(_rtDataValueDic, $"Station.{ModuleName.Transporter2}.Gantry"); BeckhoffStationAxis processTransporterAxis = CommonFunction.GetValue(_rtDataValueDic, $"Station.{ModuleName.Transporter1}.Gantry"); var result = CalculateTransporterMaxMin(loaderTransporterAxis, processTransporterAxis); double distance = result.max-_biasDistanceBetweenLoaderAndProcess - result.min; _horizontalRatio = distance / _transporterLayoutHorizontalDistance; _stationMin = result.min; BeckhoffStationAxis loaderTransporterElevatorAxis= CommonFunction.GetValue(_rtDataValueDic, $"Station.{ModuleName.Transporter2}.Elevator"); BeckhoffStationAxis processTransporterElevatorAxis = CommonFunction.GetValue(_rtDataValueDic, $"Station.{ModuleName.Transporter1}.Elevator"); var verticalResult=CalculateTransporterMaxMin(loaderTransporterElevatorAxis, processTransporterElevatorAxis); double verticalDistance = verticalResult.max - verticalResult.min; _verticalRatio = verticalDistance / VERTICAL_DISTANCE; } InitialKeys(); if (_timer == null) { _timer = new DispatcherTimer(); _timer.Interval = TimeSpan.FromMilliseconds(100); _timer.Tick += Timer_Tick; } _timer.Start(); } /// /// 隐藏 /// public void Hide() { if(_timer!=null) { _timer.Stop(); } } /// /// 定时器执行 /// /// /// private void Timer_Tick(object sender, EventArgs e) { if (_rtDataKeys.Count != 0) { _rtDataValueDic = QueryDataClient.Instance.Service.PollData(_rtDataKeys); if (_rtDataValueDic != null) { LoaderGantryMotionData = CommonFunction.GetValue(_rtDataValueDic, $"{ModuleName.Transporter2}.Gantry.{MOTION_DATA}"); if (LoaderGantryMotionData != null&&LoaderGantryMotionData.IsDataInitialized) { LoaderTransporterGantryPosition = _loaderPosition + (LoaderGantryMotionData.MotorPosition - _stationMin) / _horizontalRatio - TRANSPORTER_BOX_LENGTH+LOADER_BUFFER_HALF_LENGTH; } LoaderElevatorMotionData= CommonFunction.GetValue(_rtDataValueDic, $"{ModuleName.Transporter2}.Elevator.{MOTION_DATA}"); if(LoaderElevatorMotionData!=null&&LoaderElevatorMotionData.IsDataInitialized) { LoaderTransporterElevatorPosition = LoaderElevatorMotionData.MotorPosition / _verticalRatio; } ProcessGantryMotionData = CommonFunction.GetValue(_rtDataValueDic, $"{ModuleName.Transporter1}.Gantry.{MOTION_DATA}"); if (ProcessGantryMotionData != null&&ProcessGantryMotionData.IsDataInitialized) { ProcessTransporterGantryPosition = _loaderPosition+ (ProcessGantryMotionData.MotorPosition+_biasDistanceBetweenLoaderAndProcess - _stationMin) / _horizontalRatio - TRANSPORTER_BOX_LENGTH+LOADER_BUFFER_HALF_LENGTH; } ProcessElevatorMotionData = CommonFunction.GetValue(_rtDataValueDic, $"{ModuleName.Transporter1}.Elevator.{MOTION_DATA}"); if (ProcessElevatorMotionData != null && ProcessElevatorMotionData.IsDataInitialized) { ProcessTransporterElevatorPosition = ProcessElevatorMotionData.MotorPosition / _verticalRatio; } } } } /// /// 计算Tansporter水平最大值最小值 /// /// /// /// private (double max,double min) CalculateTransporterMaxMin(BeckhoffStationAxis loaderTransporterAxis,BeckhoffStationAxis processTransporterAxis) { double max = 0; double min = double.MaxValue; foreach(Station item in loaderTransporterAxis.Stations) { double position = double.Parse(item.Position); if(position > max) { max = position; } if(position max) { max = position; } if (position < min) { min = position; } } return (max,min); } /// /// 初始化Keys /// private void InitialKeys() { _rtDataKeys.Clear(); _rtDataKeys.Add($"{ModuleName.Transporter2}.Gantry.{CURRENT_STATION}"); _rtDataKeys.Add($"{ModuleName.Transporter2}.Gantry.{MOTION_DATA}"); _rtDataKeys.Add($"{ModuleName.Transporter2}.Elevator.{CURRENT_STATION}"); _rtDataKeys.Add($"{ModuleName.Transporter2}.Elevator.{MOTION_DATA}"); _rtDataKeys.Add($"{ModuleName.Transporter1}.Gantry.{CURRENT_STATION}"); _rtDataKeys.Add($"{ModuleName.Transporter1}.Gantry.{MOTION_DATA}"); _rtDataKeys.Add($"{ModuleName.Transporter1}.Elevator.{CURRENT_STATION}"); _rtDataKeys.Add($"{ModuleName.Transporter1}.Elevator.{MOTION_DATA}"); } } }