SweepConfigViewModel.cs 31 KB

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