123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- using Avalonia.Collections;
- using Avalonia.Controls;
- using OxyPlot;
- using OxyPlot.Series;
- using Shaker.Models;
- using Shaker.Models.Tools;
- using ShakerApp.Tools;
- using ShakerApp.Views;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using System.Net.Http.Headers;
- using System.Runtime.CompilerServices;
- using System.Text;
- using System.Threading.Tasks;
- namespace ShakerApp.ViewModels
- {
- internal class SineMainPageViewModel : BaseMainPageViewModel<SineDataModel>
- {
- public const string TDMSDataName = "SweepData";
- List<OxyColor> oxyColors = new List<OxyColor>() {OxyColors.Black, OxyColors.Green, OxyColors.Red, OxyColors.Red, OxyColors.Yellow, OxyColors.Yellow };
- List<LineStyle> lineStyles = new List<LineStyle>() {LineStyle.Solid, LineStyle.Solid, LineStyle.Solid, LineStyle.Solid, LineStyle.LongDashDotDot, LineStyle.LongDashDotDot };
- List<string> properties = new List<string>() {nameof(SweepData.Acceleration), nameof(SweepData.TargetAcceleration), nameof(SweepData.UpStopAcceleration), nameof(SweepData.DownStopAcceleration), nameof(SweepData.UpWarnAcceleration), nameof(SweepData.DownWarnAcceleration) };
- List<SweepData> datas = new List<SweepData>();
- DateTime dateTime = DateTime.Now;
- OxyPlot.Annotations.ArrowAnnotation arrowAnnotation = new OxyPlot.Annotations.ArrowAnnotation();
- public AvaloniaList<LineSeries> LineSeries { get; } = new AvaloniaList<LineSeries>();
- private SineMainPageViewModel()
- {
- #region 加速度谱曲线
- PlotModel.Axes.Add(new OxyPlot.Axes.LogarithmicAxis()
- {
- MaximumPadding = 0,
- MinimumPadding = 0,
- Title = App.Current?.FindResource(ShakerConstant.FrequencyKey) + "",
- Unit = "Hz",
- MajorGridlineStyle = LineStyle.Solid,
- Position = OxyPlot.Axes.AxisPosition.Bottom,
- Key = "Freq"
- });
- PlotModel.Axes.Add(new OxyPlot.Axes.LogarithmicAxis()
- {
- Key = "Ampt",
- Title = App.Current?.FindResource(ShakerConstant.AmptAxisTitleKey) + "",
- Unit = "g",
- MajorGridlineStyle = LineStyle.Solid,
- Position = OxyPlot.Axes.AxisPosition.Left,
- });
- PlotModel.Title = App.Current?.FindResource(ShakerConstant.AccelerationSpectrumKey) + "";
- for (int i = 0; i < oxyColors.Count; i++)
- {
- LineSeries line = new LineSeries();
- line.Title = App.Current?.FindResource(ShakerConstant.ShowSweepAccelerationSpectrumNames[i]) + "";
- line.Color = oxyColors[i];
- line.StrokeThickness = 1;
- line.DataFieldX = nameof(SweepData.Frequency);
- line.DataFieldY = properties[i];
- line.LineStyle = lineStyles[i];
- line.XAxisKey = "Freq";
- line.YAxisKey = "Ampt";
- LineSeries.Add(line);
- PlotModel.Series.Add(line);
- }
- PlotModel.Annotations.Add(arrowAnnotation);
- arrowAnnotation.Selectable = false;
- arrowAnnotation.SelectionMode = OxyPlot.SelectionMode.Single;
- arrowAnnotation.Text = "Test";
- arrowAnnotation.TextColor = OxyColors.Transparent;
- arrowAnnotation.StartPoint = new DataPoint(8, 4);
- arrowAnnotation.EndPoint = new DataPoint();
- arrowAnnotation.Color = OxyColors.Transparent;
- PlotModel.Legends.Add(new OxyPlot.Legends.Legend()
- {
- ShowInvisibleSeries = true,
- });
- PlotModel.Title = App.Current?.FindResource(MainPageType.SinePage.Description()) + "";
- #endregion
- GetEvent(ShakerSettingViewModel.LANGUAGECHANGEDEVENT).Subscrip((_, _) =>
- {
- PlotModel.InvalidatePlot(false);
- PlotModel.Title = App.Current?.FindResource(MainPageType.SinePage.Description()) + "";
- PlotModel.Axes[0].Title = App.Current?.FindResource("Frequency") + "";
- PlotModel.Axes[1].Title = Title = App.Current?.FindResource("Ampt") + "";
- for(int i=0;i<LineSeries.Count;i++)
- {
- LineSeries[i].Title = App.Current?.FindResource(ShakerConstant.ShowSweepAccelerationSpectrumNames[i]) + "";
- }
- PlotModel.InvalidatePlot(true);
- });
- GetEvent<AllConfig>().Subscrip((_, _) =>
- {
- CommunicationViewModel.Instance.LocalCommunication?.GetEvent<List<SineDataModel>>()?.Subscrip((_, args) =>
- {
- UpdateData(args.Data.Cast<IResultDataModel>().ToList());
- CommunicationViewModel.Instance.ServiceCommunication?.GetEvent<List<SineDataModel>>()?.Publish(this, args.Data);
- });
- });
- }
- static SineMainPageViewModel()
- {
- }
- public override void SaveTdmsConfig(TDMS.ITDMSFile? config)
- {
- if (config == null) return;
- base.SaveTdmsConfig(config);
- var group = config.Contains(nameof(SweepConfigModel)) ? config[nameof(SweepConfigModel)]:config.AddGroup(nameof(SweepConfigModel));
- if (group == null) return;
- typeof(SweepConfigModel) .GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)
- .Select(x => (x, x.GetValue(SweepConfigViewModel.Instance.Model)))
- .ToList()
- .ForEach(x =>
- {
- if (x.Item2 == null)
- {
- return;
- }
- if (x.x.FieldType.IsAssignableTo(typeof(IList)) || x.x.FieldType.IsArray)
- {
- group.CreateOrUpdateProperty($"{x.x.Name}", string.Join("", Tools.Tools.Serialize(x.x.FieldType, x.Item2).Select(x => $"{x:X2}")));
- }
- else
- {
- group.CreateOrUpdateProperty($"{x.x.Name}", x.Item2?.ToString() ?? string.Empty);
- }
- });
- }
- public void SetRefSpectrum(List<SweepData> data)
- {
- datas.Clear();
- datas.AddRange(data);
- PlotModel.InvalidatePlot(false);
- for(int i=0;i<LineSeries.Count;i++)
- {
- LineSeries[i].ItemsSource = datas;
- }
- PlotModel.InvalidatePlot(true);
- }
- public override void Start()
- {
- SetRefSpectrum(SweepConfigViewModel.Instance.RefSpectrum);
- lastwritefreq = 0;
- }
- public override void Stop()
- {
- }
- public override void UpdateData(List<IResultDataModel> model)
- {
- if (model.Last() is SineDataModel sine)
- {
- if (sine.SweepDirection != Model.SweepDirection && sine.SweepStep != Shaker.Models.SweepStep.Stop)
- {
- SetRefSpectrum(SweepConfigViewModel.Instance.RefSpectrum);
- }
- UpDataModels(model.Cast<SineDataModel>().ToList());
- UpDateModel(sine);
- UpPlot();
- }
- }
- private double lastwritefreq = 0;
- private void UpDataModels(List<SineDataModel> models)
- {
- models.ForEach(sine =>
- {
- double currentacc = Shaker.Models.Tools.Tools.VoltageToQuantities(sine.CurrentAcceleration, ShakerConfigViewModel.Instance.AccelerationSensitivity);
- uint currentfreq = (uint)(sine.CurrentFrequency * 1000_000);
- int index = -1;
- for (int i = 0; i < datas.Count; i++)
- {
- uint tempfreq = (uint)(datas[i].Frequency * 1000_000);
- if (tempfreq == currentfreq)
- {
- index = i;
- datas[i].SetAcceleration(currentacc);
- if (sine.SweepDirection == Shaker.Models.SweepDirection.Up)
- {
- for (int j = i - 1; j >= 0; j--)
- {
- if (datas[j].Frequency > SweepConfigViewModel.Instance.EndFrequency) break;
- if (double.IsNaN(datas[j].Acceleration))
- {
- datas[j].SetAcceleration(currentacc);
- }
- else break;
- }
- }
- else
- {
- for (int j = i + 1; j < datas.Count; j++)
- {
- if (datas[j].Frequency < SweepConfigViewModel.Instance.StartFrequency) break;
- if (double.IsNaN(datas[j].Acceleration))
- {
- datas[j].SetAcceleration(currentacc);
- }
- else break;
- }
- }
- return;
- }
- else if (tempfreq > currentfreq)
- {
- if (i > 0)
- {
- index = i - 1;
- }
- else index = 0;
- break;
- }
- }
- if (index == -1) index = datas.Count - 1;
- if (sine.SweepDirection == Shaker.Models.SweepDirection.Up)
- {
- for (int j = index; j >= 0; j--)
- {
- if (datas[j].Frequency > SweepConfigViewModel.Instance.EndFrequency) break;
- if (double.IsNaN(datas[j].Acceleration))
- {
- datas[j].SetAcceleration(currentacc);
- }
- else break;
- }
- }
- else
- {
- for (int j = index + 1; j < datas.Count; j++)
- {
- if (datas[j].Frequency < SweepConfigViewModel.Instance.StartFrequency) break;
- if (double.IsNaN(datas[j].Acceleration))
- {
- datas[j].SetAcceleration(currentacc);
- }
- else break;
- }
- }
- double value = 0; double upstop = 0; double upwarn = 0; double downstop = 0; double downwarn = 0;
- SweepConfigViewModel.Instance.Model.CalcAmpt(sine.CurrentFrequency, ref value, ref upstop, ref upwarn, ref downstop, ref downwarn);
- datas.Insert(index + 1, new SweepData(sine.CurrentFrequency,currentacc, value, upstop, downstop, upwarn, downwarn));
- });
- var file = ShakerDataViewModel.Instance.File;
- if (file == null) return;
- var savemodels = models.DistinctBy(x => x.CurrentFrequency).Where(x=>x.CurrentFrequency!=lastwritefreq).ToList();
- if (savemodels.Count == 0) return;
- lastwritefreq = savemodels[^1].CurrentFrequency;
- try
- {
- var group= file.Contains(TDMSDataName) ? file[TDMSDataName]:file.AddGroup(TDMSDataName);
- if (group == null) return;
- var ch = group.Contains(nameof(SineDataModel.CurrentFrequency)) ? group[nameof(SineDataModel.CurrentFrequency)] : group.AddChannel(TDMS.Common.TDMSDataType.Double, nameof(SineDataModel.CurrentFrequency), "Hz");
- if (ch != null)
- {
- ch.AppendData(savemodels.Select(x => x.CurrentFrequency).ToArray());
- }
- ch = group.Contains(nameof(SineDataModel.CurrentAcceleration)) ? group[nameof(SineDataModel.CurrentAcceleration)] : group.AddChannel(TDMS.Common.TDMSDataType.Double,nameof(SineDataModel.CurrentAcceleration), "g");
- if (ch != null)
- {
- ch.AppendData(savemodels.Select(x => x.CurrentAcceleration).ToArray());
- }
- ch = group.Contains(nameof(SineDataModel.SweepIndex)) ? group[nameof(SineDataModel.SweepIndex)] : group.AddChannel(TDMS.Common.TDMSDataType.Int32, nameof(SineDataModel.SweepIndex), "");
- if (ch != null)
- {
- ch.AppendData(savemodels.Select(x => (int)x.SweepIndex).ToArray());
- }
- file.Save();
- }
- catch(Exception ex)
- {
- }
- }
- private void UpPlot()
- {
- PlotModel.InvalidatePlot(false);
- if (Model.SweepStep == Shaker.Models.SweepStep.Stop)
- {
- arrowAnnotation.TextColor = OxyColors.Transparent;
- arrowAnnotation.Color = OxyColors.Transparent;
- }
- else
- {
- arrowAnnotation.TextColor = OxyColors.Black;
- arrowAnnotation.Color = OxyColors.Green;
- arrowAnnotation.EndPoint = new DataPoint(CurrentFrequency, CurrentAcceleration);
- arrowAnnotation.StartPoint = new DataPoint(CurrentFrequency, 1E-30);
- arrowAnnotation.Text = $"{App.Current?.FindResource("Frequency")}:{CurrentFrequency:F2}Hz\r\n{App.Current?.FindResource("Acceleration")}:{CurrentAcceleration:F3}g";
- arrowAnnotation.TextPosition = arrowAnnotation.EndPoint;
- arrowAnnotation.TextHorizontalAlignment = HorizontalAlignment.Left;
- arrowAnnotation.TextVerticalAlignment = VerticalAlignment.Top;
- }
- for(int i=0;i<LineSeries.Count;i++)
- {
- LineSeries[i].ItemsSource = datas;
- }
- PlotModel.InvalidatePlot(true);
- }
- [PropertyAssociation(nameof(SineDataModel.TotalTime))]
- public double TotalTime { get => Model.TotalTime; set => SetProperty(ref Model.TotalTime, value); }
- [PropertyAssociation(nameof(SineDataModel.RunTime))]
- public double RunTime { get => Model.RunTime; set => SetProperty(ref Model.RunTime, value); }
- [PropertyAssociation(nameof(SineDataModel.CurrentFrequency))]
- public double CurrentFrequency { get => Model.CurrentFrequency; set => SetProperty(ref Model.CurrentFrequency, value); }
- [PropertyAssociation(nameof(SineDataModel.CurrentAcceleration))]
- public double CurrentAcceleration { get => Shaker.Models.Tools.Tools.VoltageToQuantities(Model.CurrentAcceleration, ShakerConfigViewModel.Instance.AccelerationSensitivity); set => SetProperty(ref Model.CurrentAcceleration, value); }
- [PropertyAssociation(nameof(SineDataModel.SweepDirection))]
- public string SweepDirection { get => Model.SweepDirection.Description(); }
- [PropertyAssociation(nameof(SineDataModel.SweepStep))]
- public string SweepStep { get => Model.SweepStep.Description(); }
- [PropertyAssociation(nameof(SineDataModel.SweepIndex))]
- public uint SweepIndex { get => Model.SweepIndex; set => SetProperty(ref Model.SweepIndex, value); }
- [PropertyAssociation(nameof(SineDataModel.MainPageType))]
- public override MainPageType PageType => Model.MainPageType;
- public OxyPlot.PlotModel PlotModel { get; private set; } = new OxyPlot.PlotModel();
- public static SineMainPageViewModel Instance { get; } = new SineMainPageViewModel();
- public OxyPlot.PlotModel DriverModel { get; private set; } = new PlotModel();
- }
- }
|