using FLY.Thick.Blowing.IService; using GalaSoft.MvvmLight.Command; using LiveCharts; using LiveCharts.Configurations; using Misc; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FLY.KSL.UI.Client { public class PgHeatAnalyseVmUt : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; #region 图表控制 public Func YFormatter { get; private set; } public int XMax { get; private set; } public double YMax => MaxHeat / 2; public double YMin => -MaxHeat / 2; #endregion /// /// 厚度偏差% /// public ChartValues ThickPercentDiffs { get; } = new ChartValues(); /// /// 加热偏差% /// public ChartValues HeatDiffs { get; } = new ChartValues(); /// /// 加热偏差% 高斯滤波后 /// public ChartValues HeatDiffEffects { get; } = new ChartValues(); public object MapperHeats { get; private set; } [PropertyChanged.DependsOn(nameof(Kp))] public object MapperThickPercents { get; private set; } #region 参数 /// /// 比例因子 /// public double Kp { get; set; } = 3; public int MaxHeat { get; set; } = 100; /// /// 复位区号 /// public int OrgBoltNo { get; set; } = 1; /// /// 反向 /// public bool IsReversed { get; set; } = false; #endregion #region 状态 /// /// 当前厚度%变化极差 单位% /// public double CurrMaxMin { get; set; } = -1; /// /// 当前加热与厚度相关性 /// public double CurrHeatThickR { get; set; } = -1; /// /// 当前加热与厚度 比例 /// public double CurrKp { get; set; } = -1; /// /// 数据异常,不能比较 /// public bool IsError { get; set; } #endregion #region 分区表 public ObservableCollection BoltMap { get; } = new ObservableCollection(); /// /// 加热生效曲线,允许为空,则不生效 /// public int[] HeatEffectCurve { get; set; } public bool IsUsedMap { get; set; } #endregion public RelayCommand KpCollapseCmd { get; } public RelayCommand KpExpandCmd { get; } public RelayCommand LeftCmd { get; } public RelayCommand RightCmd { get; } public RelayCommand AutoCmd { get; } public RelayCommand ApplyCmd { get; } public RelayCommand TestMapCmd { get; } public RelayCommand DelMapCmd { get; } public PgHeatAnalyseVmUt() { YFormatter = (y) => { string text = y + "%"; return $"{text,6}"; }; MapperHeats = Mappers.Xy() .X((value, index) => { return index + 1; }) .Y((value, index) => { return value; }); MapperThickPercents = Mappers.Xy() .X((value, index) => { return index + 1; }) .Y((value) => { return value * Kp; }); double target = 150; double tolerance = target * 0.02; int nbolts = 100; double[] datas = new double[nbolts]; Random random = new Random(); for (int i = 0; i < nbolts; i++) { datas[i] = (Math.Sin(i * Math.PI / nbolts) * 3) * tolerance + target + (random.NextDouble() - 0.5) * 1 - 6; } int kp = 3; double[] heats = new double[nbolts]; for (int i = 0; i < nbolts; i++) { heats[i] = ((Math.Sin(i * Math.PI / nbolts)) * 20 + 30 + (random.NextDouble() - 0.5) * 5); } //对中!!! double avg = heats.Average(); for (int i = 0; i < nbolts; i++) { heats[i] -= avg; } XMax = nbolts + 1; OrgBoltNo = 20; avg = datas.AverageNoNull(); double[] thickPercents = new double[datas.Count()]; for (int i = 0; i < datas.Count(); i++) { var data = datas[i]; var percent = 0.0; if (!double.IsNaN(data)) { percent = (data - avg) / avg * 100 * Kp; } thickPercents[i] = percent; } ThickPercentDiffs.Clear(); ThickPercentDiffs.AddRange(thickPercents); Kp = kp; HeatDiffs.Clear(); HeatDiffs.AddRange(heats); //滤波后 BoltMap.Add(new BoltMapCell() { OldNo = 20, NewNo = 20 }); BoltMap.Add(new BoltMapCell() { OldNo = 30, NewNo = 40 }); BoltMap.Add(new BoltMapCell() { OldNo = 60, NewNo = 60 }); HeatEffectCurve = new int[] { 3, 4, 6, 4, 3 }; var heatEffects = FLY.KSL.Common.MyMath.Filter(heats, HeatEffectCurve.Select(d => (double)d)); HeatDiffEffects.AddRange(heatEffects); } } }