SweepConfigViewModel.cs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. using Avalonia.Collections;
  2. using Avalonia.Controls;
  3. using Avalonia.Utilities;
  4. using CommunityToolkit.Mvvm.Input;
  5. using OxyPlot;
  6. using OxyPlot.Series;
  7. using Shaker.Model;
  8. using Shaker.Model.Tools;
  9. using Shaker.Models;
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Linq;
  13. using System.Linq.Expressions;
  14. using System.Text;
  15. using System.Threading.Tasks;
  16. using System.Windows.Input;
  17. namespace ShakerApp.ViewModels
  18. {
  19. internal class SweepConfigViewModel:ViewModelBase<Shaker.Models.SweepConfigModel>
  20. {
  21. private float interval = 0.1f;
  22. List<OxyPlot.Series.LineSeries> lineSeries = new List<OxyPlot.Series.LineSeries>();
  23. List<DataPoint> velocitydata = new List<DataPoint>();
  24. LineSeries velocity = new LineSeries();
  25. LineSeries displacement = new LineSeries();
  26. List<DataPoint> displacementdata = new List<DataPoint>();
  27. List<OxyColor> oxyColors = new List<OxyColor>() { OxyColors.Green, OxyColors.Red, OxyColors.Red, OxyColors.Yellow, OxyColors.Yellow };
  28. List<LineStyle> lineStyles = new List<LineStyle>() { LineStyle.Solid, LineStyle.Solid, LineStyle.Solid, LineStyle.LongDashDotDot, LineStyle.LongDashDotDot };
  29. List<string> properties = new List<string>() { nameof(SweepData.TargetAcceleration), nameof(SweepData.UpStopAcceleration), nameof(SweepData.DownStopAcceleration), nameof(SweepData.UpWarnAcceleration), nameof(SweepData.DownWarnAcceleration) };
  30. List<SweepData> datas = new List<SweepData>();
  31. private SweepConfigViewModel()
  32. {
  33. OnceSweepTime = Model.OCTToTime(Model.SweepSpeed);
  34. Content = typeof(Views.SweepConfigView);
  35. for(int i=0;i<ShakerConfigViewModel.Instance.AccelerationSensorCount;i++)
  36. {
  37. Channels.Add(new KeyValuePair<int, int>(i+1,i));
  38. }
  39. #region 加速度谱曲线
  40. AccelerationModel.Axes.Add(new OxyPlot.Axes.LogarithmicAxis()
  41. {
  42. MaximumPadding = 0,
  43. MinimumPadding = 0,
  44. Title = App.Current?.FindResource(Shaker.Model.ShakerConstant.FrequencyKey) + "",
  45. Unit = "Hz",
  46. MajorGridlineStyle = LineStyle.Solid,
  47. Position = OxyPlot.Axes.AxisPosition.Bottom,
  48. Key = "Freq"
  49. });
  50. AccelerationModel.Axes.Add(new OxyPlot.Axes.LogarithmicAxis()
  51. {
  52. Key= "Ampt",
  53. Title = App.Current?.FindResource(ShakerConstant.AmptAxisTitleKey)+"",
  54. Unit="g",
  55. MajorGridlineStyle = LineStyle.Solid,
  56. Position = OxyPlot.Axes.AxisPosition.Left,
  57. });
  58. AccelerationModel.Title = App.Current?.FindResource(ShakerConstant.AccelerationSpectrumKey)+ "";
  59. for(int i=0;i<oxyColors.Count;i++)
  60. {
  61. LineSeries line = new LineSeries();
  62. line.Title = App.Current?.FindResource(ShakerConstant.SweepAccelerationSpectrumNames[i])+"";
  63. line.Color = oxyColors[i];
  64. line.StrokeThickness = 1;
  65. line.DataFieldX = nameof(SweepData.Frequency);
  66. line.DataFieldY = properties[i];
  67. line.LineStyle = lineStyles[i];
  68. line.XAxisKey = "Freq";
  69. line.YAxisKey = "Ampt";
  70. lineSeries.Add(line);
  71. AccelerationModel.Series.Add(line);
  72. }
  73. AccelerationModel.Legends.Add(new OxyPlot.Legends.Legend()
  74. {
  75. ShowInvisibleSeries = true,
  76. });
  77. #endregion
  78. #region 速度
  79. VelocityModel.Axes.Add(new OxyPlot.Axes.LogarithmicAxis()
  80. {
  81. MaximumPadding = 0,
  82. MinimumPadding = 0,
  83. Title = App.Current?.FindResource(Shaker.Model.ShakerConstant.FrequencyKey) + "",
  84. Unit = "Hz",
  85. MajorGridlineStyle = LineStyle.Solid,
  86. Position = OxyPlot.Axes.AxisPosition.Bottom,
  87. Key = "Freq"
  88. });
  89. VelocityModel.Title = App.Current?.FindResource(ShakerConstant.VelocityKey) + "";
  90. VelocityModel.Axes.Add(new OxyPlot.Axes.LogarithmicAxis()
  91. {
  92. Key = "Ampt",
  93. Title = App.Current?.FindResource(ShakerConstant.AmptAxisTitleKey) + "",
  94. Unit = "m/s",
  95. MajorGridlineStyle = LineStyle.Solid,
  96. Position = OxyPlot.Axes.AxisPosition.Left,
  97. });
  98. velocity = new LineSeries();
  99. velocity.Title = App.Current?.FindResource(ShakerConstant.VelocityKey) + "";
  100. velocity.Color = oxyColors[0];
  101. velocity.StrokeThickness = 1;
  102. velocity.DataFieldX = nameof(DataPoint.X);
  103. velocity.DataFieldY = nameof(DataPoint.Y);
  104. velocity.LineStyle = lineStyles[0];
  105. velocity.XAxisKey = "Freq";
  106. velocity.YAxisKey = "Ampt";
  107. VelocityModel.Series.Add(velocity);
  108. #endregion
  109. #region 位移
  110. DisplacementModel.Axes.Add(new OxyPlot.Axes.LogarithmicAxis()
  111. {
  112. MaximumPadding = 0,
  113. MinimumPadding = 0,
  114. Title = App.Current?.FindResource(Shaker.Model.ShakerConstant.FrequencyKey) + "",
  115. Unit = "Hz",
  116. MajorGridlineStyle = LineStyle.Solid,
  117. Position = OxyPlot.Axes.AxisPosition.Bottom,
  118. Key = "Freq"
  119. });
  120. DisplacementModel.Title = App.Current?.FindResource(ShakerConstant.DisplacementKey) + "";
  121. DisplacementModel.Axes.Add(new OxyPlot.Axes.LogarithmicAxis()
  122. {
  123. Key = "Ampt",
  124. Title = App.Current?.FindResource(ShakerConstant.AmptAxisTitleKey) + "",
  125. Unit = "mm",
  126. MajorGridlineStyle = LineStyle.Solid,
  127. Position = OxyPlot.Axes.AxisPosition.Left,
  128. });
  129. displacement = new LineSeries();
  130. displacement.Title = App.Current?.FindResource(ShakerConstant.DisplacementKey) + "";
  131. displacement.Color = oxyColors[0];
  132. displacement.StrokeThickness = 1;
  133. displacement.DataFieldX = nameof(DataPoint.X);
  134. displacement.DataFieldY = nameof(DataPoint.Y);
  135. displacement.LineStyle = lineStyles[0];
  136. displacement.XAxisKey = "Freq";
  137. displacement.YAxisKey = "Ampt";
  138. DisplacementModel.Series.Add(displacement);
  139. #endregion
  140. GetEvent(ShakerSettingViewModel.LANGUAGECHANGEDEVENT).Subscrip((_, _) =>
  141. {
  142. AccelerationModel.InvalidatePlot(false);
  143. AccelerationModel.Axes[0].Title = App.Current?.FindResource(ShakerConstant.FrequencyKey) + "";
  144. AccelerationModel.Axes[1].Title = App.Current?.FindResource(ShakerConstant.AmptAxisTitleKey) + "";
  145. AccelerationModel.Title = App.Current?.FindResource(ShakerConstant.AccelerationSpectrumKey) + "";
  146. for(int i=0;i<lineSeries.Count;i++)
  147. {
  148. lineSeries[i].Title = App.Current?.FindResource(ShakerConstant.SweepAccelerationSpectrumNames[i]) + "";
  149. }
  150. AccelerationModel.InvalidatePlot(true);
  151. VelocityModel.InvalidatePlot(false);
  152. VelocityModel.Axes[0].Title = App.Current?.FindResource(ShakerConstant.FrequencyKey) + "";
  153. VelocityModel.Axes[1].Title = App.Current?.FindResource(ShakerConstant.AmptAxisTitleKey) + "";
  154. VelocityModel.Title = App.Current?.FindResource(ShakerConstant.VelocityKey) + "";
  155. velocity.Title = App.Current?.FindResource(ShakerConstant.VelocityKey) + "";
  156. VelocityModel.InvalidatePlot(true);
  157. DisplacementModel.InvalidatePlot(false);
  158. DisplacementModel.Axes[0].Title = App.Current?.FindResource(ShakerConstant.FrequencyKey) + "";
  159. DisplacementModel.Axes[1].Title = App.Current?.FindResource(ShakerConstant.AmptAxisTitleKey) + "";
  160. DisplacementModel.Title = App.Current?.FindResource(ShakerConstant.DisplacementKey) + "";
  161. displacement.Title = App.Current?.FindResource(ShakerConstant.DisplacementKey) + "";
  162. DisplacementModel.InvalidatePlot(true);
  163. });
  164. GetEvent<AllConfig>().Subscrip((sender, args) =>
  165. {
  166. UpDateModel(args.Data.SweepConfig);
  167. if(CommunicationViewModel.Intance.ServiceIsStart)
  168. {
  169. CommunicationViewModel.Intance.ServiceCommunication.GetEvent<SweepConfigModel>().Publish(this, args.Data.SweepConfig);
  170. }
  171. CommunicationViewModel.Intance.LocalCommunication?.GetEvent<SweepConfigModel>()?.Subscrip((sender, args) =>
  172. {
  173. UpDateModel(args.Data);
  174. Refresh();
  175. SineMainPageViewModel.Instance.SetRefSpectrum(datas);
  176. CommunicationViewModel.Intance.ServiceCommunication?.GetEvent<SweepConfigModel>()?.Publish(this, Model);
  177. });
  178. });
  179. }
  180. static SweepConfigViewModel()
  181. {
  182. }
  183. public AvaloniaList<KeyValuePair<int,int>> Channels { get; } = new AvaloniaList<KeyValuePair<int,int>>();
  184. public int SelectChannel
  185. {
  186. get => Model.SelectChannel;
  187. set
  188. {
  189. SetProperty(ref Model.SelectChannel, value);
  190. for(int i=0;i<ShakerConfigViewModel.Instance.AccelerationSensorCount;i++)
  191. {
  192. ShakerConfigViewModel.Instance.Accelerations[i].Value.Weight = value == i ? 1 : 0;
  193. }
  194. }
  195. }
  196. public int MaxSweepItemCount => Model.MaxSweepItemCount;
  197. public uint SweepCount { get => Model.SweepCount; set => SetProperty(ref Model.SweepCount, value); }
  198. public SweepType SweepType
  199. {
  200. get => Model.SweepType;
  201. set
  202. {
  203. if (Model.SweepType == value) return;
  204. SetProperty(ref Model.SweepType, value);
  205. Model.OnceSweepTime = Model.OCTToTime(Model.SweepSpeed);
  206. OnPropertyChanged(nameof(OnceSweepTime));
  207. }
  208. }
  209. public SweepDirection SweepDirection { get => Model.SweepDirection; set => SetProperty(ref Model.SweepDirection, value); }
  210. public SignalType SignalType
  211. {
  212. get => Model.SignalType;
  213. set
  214. {
  215. SetProperty(ref Model.SignalType, value);
  216. if(value == SignalType.Sweep)
  217. {
  218. OnceSweepTime = Model.OCTToTime(Model.SweepSpeed);
  219. }
  220. }
  221. }
  222. public float StartFrequency
  223. {
  224. get => Model.StartFrequency;
  225. set
  226. {
  227. if (value == Model.StartFrequency) return;
  228. SetProperty(ref Model.StartFrequency, value);
  229. if (SignalType == SignalType.Fixed) return;
  230. OnceSweepTime = Model.OCTToTime(Model.SweepSpeed);
  231. }
  232. }
  233. public ICommand MaxLoadCommand => new RelayCommand(MaxLoad);
  234. private void MaxLoad()
  235. {
  236. SweepItems.Clear();
  237. SweepItems.Add(new IndexValueItemViewModel<SweepItemViewModel>(1,new SweepItemViewModel(new SweepItemModel()
  238. {
  239. Frequency = ShakerConfigViewModel.Instance.MinFrequency,
  240. Value = ShakerConfigViewModel.Instance.MaxDisplacement,
  241. SweepValueType = SweepValueType.FixedDisplacement,
  242. })));
  243. SweepItems.Add(new IndexValueItemViewModel<SweepItemViewModel>(2,new SweepItemViewModel( new SweepItemModel()
  244. {
  245. Frequency = ShakerConfigViewModel.Instance.MinFrequency + interval,
  246. Value = ShakerConfigViewModel.Instance.MaxVelocity,
  247. SweepValueType = SweepValueType.FixedVelocity,
  248. })));
  249. SweepItems.Add(new IndexValueItemViewModel<SweepItemViewModel>(3,new SweepItemViewModel( new SweepItemModel()
  250. {
  251. Frequency = ShakerConfigViewModel.Instance.MinFrequency + interval * 2,
  252. Value = ShakerConfigViewModel.Instance.MaxAcceleration,
  253. SweepValueType = SweepValueType.FixedAcceleration,
  254. })));
  255. SweepItems.Add(new IndexValueItemViewModel<SweepItemViewModel>(4,new SweepItemViewModel( new SweepItemModel()
  256. {
  257. Frequency = ShakerConfigViewModel.Instance.MaxFrequency,
  258. Value = ShakerConfigViewModel.Instance.MaxAcceleration,
  259. SweepValueType = SweepValueType.FixedAcceleration,
  260. })));
  261. Refresh();
  262. }
  263. public float MaxAcceleration => datas.Count ==0 ?0: datas.Max(x => x.TargetAcceleration);
  264. public double MaxDisplacement => displacementdata.Count == 0 ? 0 : displacementdata.Max(x => x.Y);
  265. public double MaxVelocity => velocitydata.Count == 0 ? 0 : velocitydata.Max(x => x.Y);
  266. public bool AccelerationOverLimit => MaxAcceleration >= ShakerConfigViewModel.Instance.MaxAcceleration;
  267. public bool DisplacementOverLimit => MaxDisplacement > ShakerConfigViewModel.Instance.MaxDisplacement;
  268. public bool VelocityOverLimit => MaxVelocity > ShakerConfigViewModel.Instance.MaxVelocity;
  269. public float AccelerationLoad => MathF.Round(MaxAcceleration / ShakerConfigViewModel.Instance.MaxAcceleration * 100f, 2);
  270. public float DisplacementLoad => MathF.Round((float)MaxDisplacement / ShakerConfigViewModel.Instance.MaxDisplacement * 100f, 2);
  271. public float VelocityLoad => MathF.Round((float)MaxVelocity / ShakerConfigViewModel.Instance.MaxVelocity * 100f, 2);
  272. public float EndFrequency
  273. {
  274. get => Model.EndFrequency;
  275. set
  276. {
  277. if (value == Model.EndFrequency) return;
  278. SetProperty(ref Model.EndFrequency, value);
  279. if (SignalType == SignalType.Fixed) return;
  280. OnceSweepTime = Model.OCTToTime(Model.SweepSpeed);
  281. }
  282. }
  283. public float OnceSweepTime
  284. {
  285. get => Model.OnceSweepTime;
  286. set
  287. {
  288. if (MathF.Abs(value - Model.OnceSweepTime) <= Increment || float.IsNaN(value)) return;
  289. SetProperty(ref Model.OnceSweepTime, value);
  290. OnPropertyChanged(nameof(TotalSweepTime));
  291. if (SignalType == SignalType.Fixed) return;
  292. SweepSpeed = Model.TimeToOCT(value);
  293. }
  294. }
  295. private bool VerifySweepItem()
  296. {
  297. if (SweepItems.Count < 2)
  298. {
  299. Dialogs.Error(string.Format(App.Current?.FindResource("SweepItemsCountError")+"",2));
  300. return false;
  301. }
  302. Model.SweepItems = SweepItems.Select(x => x.Value.Model).Where(x=>x.Value >0).OrderBy(x => x.Frequency).DistinctBy(x => x.Frequency).ToList();
  303. SweepItems.Clear();
  304. if (Model.SweepItems.Count < 2)
  305. {
  306. for (int i = 0; i < Model.SweepItems.Count; i++)
  307. {
  308. SweepItems.Add(new IndexValueItemViewModel<SweepItemViewModel>(i + 1, new SweepItemViewModel(Model.SweepItems[i])));
  309. }
  310. Dialogs.Error(string.Format(App.Current?.FindResource("SweepItemsCountError") + "", 2));
  311. return false;
  312. }
  313. else
  314. {
  315. for (int i = 0; i < Model.SweepItems.Count; i++)
  316. {
  317. if (i == 0)
  318. {
  319. SweepItems.Add(new IndexValueItemViewModel<SweepItemViewModel>(i + 1, new SweepItemViewModel(Model.SweepItems[i])));
  320. continue;
  321. }
  322. switch (Model.SweepItems[i].SweepValueType)
  323. {
  324. case SweepValueType.DynamicAcceleration:
  325. case SweepValueType.FixedAcceleration:
  326. {
  327. switch(Model.SweepItems[i-1].SweepValueType)
  328. {
  329. case SweepValueType.DynamicAcceleration:
  330. break;
  331. case SweepValueType.FixedAcceleration:
  332. break;
  333. case SweepValueType.FixedDisplacement:
  334. Model.SweepItems[i].Frequency =MathF.Round(MathF.Sqrt(Model.SweepItems[i].Value*9800 / Model.SweepItems[i - 1].Value) / (2 * MathF.PI),2);
  335. break;
  336. case SweepValueType.FixedVelocity:
  337. Model.SweepItems[i].Frequency = MathF.Round(Model.SweepItems[i].Value * 9.8f / (2 * MathF.PI * Model.SweepItems[i - 1].Value), 2);
  338. break;
  339. }
  340. }
  341. break;
  342. case SweepValueType.FixedDisplacement:
  343. {
  344. switch(Model.SweepItems[i-1].SweepValueType)
  345. {
  346. case SweepValueType.DynamicAcceleration:
  347. case SweepValueType.FixedAcceleration:
  348. Model.SweepItems[i].Frequency = MathF.Round(MathF.Sqrt(Model.SweepItems[i-1].Value * 9800 / Model.SweepItems[i].Value) / (2 * MathF.PI), 2);
  349. break;
  350. case SweepValueType.FixedVelocity:
  351. Model.SweepItems[i].Frequency = MathF.Round(Model.SweepItems[i - 1].Value * 1000 / (2 * MathF.PI * Model.SweepItems[i].Value), 2);
  352. break;
  353. case SweepValueType.FixedDisplacement:
  354. break;
  355. }
  356. }
  357. break;
  358. case SweepValueType.FixedVelocity:
  359. {
  360. switch (Model.SweepItems[i - 1].SweepValueType)
  361. {
  362. case SweepValueType.DynamicAcceleration:
  363. case SweepValueType.FixedAcceleration:
  364. Model.SweepItems[i].Frequency = MathF.Round(Model.SweepItems[i-1].Value * 9.8f / (2 * MathF.PI * Model.SweepItems[i].Value), 2);
  365. break;
  366. case SweepValueType.FixedVelocity:
  367. break;
  368. case SweepValueType.FixedDisplacement:
  369. Model.SweepItems[i].Frequency = MathF.Round(Model.SweepItems[i].Value * 1000 / (2 * MathF.PI * Model.SweepItems[i-1].Value), 2);
  370. break;
  371. }
  372. }
  373. break;
  374. }
  375. SweepItems.Add(new IndexValueItemViewModel<SweepItemViewModel>(i + 1, new SweepItemViewModel(Model.SweepItems[i])));
  376. }
  377. }
  378. return true;
  379. }
  380. public ICommand RefreshCommand => new RelayCommand(Refresh);
  381. private void Refresh()
  382. {
  383. var result = VerifySweepItem();
  384. if (MaxFrequency <= MinFrequency) return;
  385. if (EndFrequency > MaxFrequency) EndFrequency = MaxFrequency;
  386. if (StartFrequency < MinFrequency) StartFrequency = MinFrequency;
  387. if (!result) return;
  388. datas.Clear();
  389. velocitydata.Clear();
  390. displacementdata.Clear();
  391. int count = (int)MathF.Ceiling((MaxFrequency - MinFrequency) / interval)+1;
  392. for(int i=0;i<count;i++)
  393. {
  394. float freq = i * interval + MinFrequency;
  395. float acc = 0;
  396. float upstop = 0;
  397. float upwarn = 0;
  398. float downstop = 0;
  399. float downwarn = 0;
  400. Model.CalcAmpt(freq, ref acc, ref upstop, ref upwarn, ref downstop, ref downwarn);
  401. datas.Add(new SweepData()
  402. {
  403. Frequency =freq,
  404. TargetAcceleration= MathF.Round(acc,4),
  405. UpStopAcceleration = upstop,
  406. UpWarnAcceleration = upwarn,
  407. DownStopAcceleration = downstop,
  408. DownWarnAcceleration = downwarn,
  409. });
  410. velocitydata.Add(new DataPoint(freq,MathF.Round(Shaker.Model.Tools.Tools.AccelerationToVelocity(acc,freq),4)));
  411. displacementdata.Add(new DataPoint(freq,MathF.Round(Shaker.Model.Tools.Tools.AccelerationToDisplacement(acc, freq),4)));
  412. }
  413. AccelerationModel.InvalidatePlot(false);
  414. VelocityModel.InvalidatePlot(false);
  415. DisplacementModel.InvalidatePlot(false);
  416. for(int i=0;i<lineSeries.Count;i++)
  417. {
  418. lineSeries[i].ItemsSource = datas;
  419. }
  420. velocity.ItemsSource = velocitydata;
  421. displacement.ItemsSource = displacementdata;
  422. VelocityModel.InvalidatePlot(true);
  423. DisplacementModel.InvalidatePlot(true);
  424. AccelerationModel.InvalidatePlot(true);
  425. OnPropertyChanged(nameof(MaxAcceleration));
  426. OnPropertyChanged(nameof(MaxVelocity));
  427. OnPropertyChanged(nameof(MaxDisplacement));
  428. OnPropertyChanged(nameof(AccelerationLoad));
  429. OnPropertyChanged(nameof(VelocityLoad));
  430. OnPropertyChanged(nameof(DisplacementLoad));
  431. OnPropertyChanged(nameof(AccelerationOverLimit));
  432. OnPropertyChanged(nameof(VelocityOverLimit));
  433. OnPropertyChanged(nameof(DisplacementOverLimit));
  434. OnPropertyChanged(nameof(MaxFrequency));
  435. OnPropertyChanged(nameof(MinFrequency));
  436. }
  437. public float SweepSpeed
  438. {
  439. get => Model.SweepSpeed;
  440. set
  441. {
  442. if (MathF.Abs(value - Model.SweepSpeed)<=Increment || float.IsNaN(value)) return;
  443. SetProperty(ref Model.SweepSpeed, value);
  444. OnceSweepTime = Model.OCTToTime(value);
  445. }
  446. }
  447. public float Increment => Model.Increment;
  448. public float TotalSweepTime => OnceSweepTime * SweepCount;
  449. public bool AddEnabled => SweepItems.Count < MaxSweepItemCount;
  450. public bool DeleteEnabled => SweepItems.Count > 0;
  451. public bool RefreshEnabled => SweepItems.Count >= 2;
  452. public float SweepStartLevel { get => Model.SweepStartLevel; set => SetProperty(ref Model.SweepStartLevel, value); }
  453. public float CrossoverPoint { get => Model.CrossoverPoint; set => SetProperty(ref Model.CrossoverPoint, value); }
  454. public float SweepLevelGain { get => Model.SweepLevelGain; set => SetProperty(ref Model.SweepLevelGain, value); }
  455. public float LowFrequencyMinCorrect { get => Model.LowFrequencyMinCorrect; set => SetProperty(ref Model.LowFrequencyMinCorrect, value); }
  456. public float LowFrequencyMaxCorrect { get => Model.LowFrequencyMaxCorrect; set => SetProperty(ref Model.LowFrequencyMaxCorrect, value); }
  457. public float HigthFrequencyMinCorrect { get => Model.HigthFrequencyMinCorrect; set => SetProperty(ref Model.HigthFrequencyMinCorrect, value); }
  458. public float HigthFrequencyMaxCorrect { get => Model.HigthFrequencyMaxCorrect; set => SetProperty(ref Model.HigthFrequencyMaxCorrect, value); }
  459. public AvaloniaList<IndexValueItemViewModel<SweepItemViewModel>> SweepItems { get; } = new AvaloniaList<IndexValueItemViewModel<SweepItemViewModel>>();
  460. public ICommand AddCommand => new RelayCommand(Add);
  461. public float MaxFrequency => SweepItems.Count ==0 ? ShakerConfigViewModel.Instance.MaxFrequency: SweepItems.Max(x=>x.Value.Frequency);
  462. public float MinFrequency => SweepItems.Count ==0 ? ShakerConfigViewModel.Instance.MinFrequency: SweepItems.Min(x => x.Value.Frequency);
  463. private void Add()
  464. {
  465. if (SweepItems.Count >= MaxSweepItemCount) return;
  466. Model.SweepItems.Add(new SweepItemModel());
  467. SweepItems.Add(new IndexValueItemViewModel<SweepItemViewModel>(SweepItems.Count + 1,new SweepItemViewModel(Model.SweepItems[^1])));
  468. OnPropertyChanged(nameof(AddEnabled));
  469. OnPropertyChanged(nameof(DeleteEnabled));
  470. OnPropertyChanged(nameof(RefreshEnabled));
  471. OnPropertyChanged(nameof(MaxFrequency));
  472. OnPropertyChanged(nameof(MinFrequency));
  473. if (MaxFrequency <= MinFrequency) return;
  474. if (EndFrequency > MaxFrequency) EndFrequency = MaxFrequency;
  475. if (StartFrequency < MinFrequency) StartFrequency = MinFrequency;
  476. }
  477. public ICommand DeleteCommand => new RelayCommand(Delete);
  478. private void Delete()
  479. {
  480. if (SweepItems.Count == 0) return;
  481. Model.SweepItems.RemoveAt(Model.SweepItems.Count - 1);
  482. SweepItems.RemoveAt(SweepItems.Count - 1);
  483. OnPropertyChanged(nameof(AddEnabled));
  484. OnPropertyChanged(nameof(DeleteEnabled));
  485. OnPropertyChanged(nameof(RefreshEnabled));
  486. OnPropertyChanged(nameof(MaxFrequency));
  487. OnPropertyChanged(nameof(MinFrequency));
  488. if (MaxFrequency <= MinFrequency) return;
  489. if (EndFrequency > MaxFrequency) EndFrequency = MaxFrequency;
  490. if (StartFrequency < MinFrequency) StartFrequency = MinFrequency;
  491. }
  492. public override void UpDateModel(SweepConfigModel model)
  493. {
  494. base.UpDateModel(model);
  495. int count = model.SweepItems.Count - SweepItems.Count;
  496. if(count>0)
  497. {
  498. for(int i=0;i<count;i++)
  499. {
  500. SweepItems.Add(new IndexValueItemViewModel<SweepItemViewModel>(SweepItems.Count + 1, new SweepItemViewModel()));
  501. }
  502. }
  503. else if(count<0)
  504. {
  505. SweepItems.RemoveRange(SweepItems.Count + count, Math.Abs(count));
  506. }
  507. else
  508. {
  509. }
  510. for(int i=0;i<SweepItems.Count;i++)
  511. {
  512. SweepItems[i].Value.UpDateModel(model.SweepItems[i]);
  513. }
  514. }
  515. protected override void Save()
  516. {
  517. base.Save();
  518. SineMainPageViewModel.Instance.SetRefSpectrum(datas);
  519. CommunicationViewModel.Intance.LocalCommunication?.GetEvent<SweepConfigModel>()?.Publish(this, Model);
  520. CommunicationViewModel.Intance.ServiceCommunication?.GetEvent<SweepConfigModel>()?.Publish(this, Model);
  521. }
  522. public List<SweepData> RefSpectrum => datas;
  523. public OxyPlot.PlotModel AccelerationModel { get; } = new OxyPlot.PlotModel();
  524. public PlotModel DisplacementModel { get; } = new PlotModel();
  525. public PlotModel VelocityModel { get; } = new PlotModel();
  526. public static SweepConfigViewModel Instance { get; } = new SweepConfigViewModel();
  527. }
  528. }