Bladeren bron

修改了fft算法,使得结果和ni中结果保持一致

luo 1 maand geleden
bovenliggende
commit
384579733f
42 gewijzigde bestanden met toevoegingen van 410 en 240 verwijderingen
  1. 4 0
      .editorconfig
  2. 4 4
      Avalonia/ShakerApp/ViewModels/MainPage/RandomMainPageViewModel.cs
  3. 2 1
      Avalonia/ShakerApp/ViewModels/MainPage/SineMainPageViewModel.cs
  4. 79 53
      Avalonia/ShakerApp/ViewModels/MainViewModel.cs
  5. 15 15
      Avalonia/ShakerApp/ViewModels/Oil/OilSourceStatusViewModel.cs
  6. 0 4
      Avalonia/ShakerApp/ViewModels/ShakerConfig/RandomConfigViewModel.cs
  7. 7 4
      Avalonia/ShakerApp/ViewModels/ShakerConfig/ShakerConfigViewModel.cs
  8. 0 4
      Avalonia/ShakerApp/ViewModels/ShakerConfig/SweepConfigViewModel.cs
  9. 4 6
      Avalonia/ShakerApp/ViewModels/ShakerControl/ShakerControlViewModel.cs
  10. 10 14
      Avalonia/ShakerApp/ViewModels/ShakerStatus/ShakerStatusViewModel.cs
  11. 10 0
      Avalonia/ShakerApp/ViewModels/ViewModelBase.cs
  12. 1 1
      Avalonia/ShakerApp/Views/ShakerConfig/ShakerConfigView.axaml
  13. 22 15
      Calc/FFTW/DFT.cs
  14. 1 2
      Calc/FFTW/FftwInterop.cs
  15. 1 1
      Calc/FFTW/FftwPlan.cs
  16. 3 1
      Calc/FxpConvert.Common/ICalc.cs
  17. 32 2
      Calc/SIMDFxpConvert/SIMDCalc.cs
  18. 9 2
      Calc/SIMDFxpConvert/SIMDFxpConvert.csproj
  19. BIN
      Calc/SIMDFxpConvert/libs/libfftw3-3-x64.dll
  20. BIN
      Calc/SIMDFxpConvert/libs/libfftw3-3-x86.dll
  21. BIN
      Calc/SIMDFxpConvert/libs/libfftw3.so
  22. 4 4
      Communication/ActiveMQCommunication/Communication.cs
  23. 8 8
      Communication/LocalCommunication/Communication.cs
  24. 4 4
      EventBroker/EventBroker.Common/IEventBroker.cs
  25. 1 0
      Shaker.Model/Models/ShakerConfigModel.cs
  26. 0 1
      Shaker.Model/Models/ShakerControlModel.cs
  27. 20 20
      Shaker/ClassDiagram1.cd
  28. 6 0
      Shaker/OilSource/BitAddressConfig.cs
  29. 32 32
      Shaker/OilSource/OilSource.cs
  30. 33 0
      Shaker/OilSource/OilSourceAnalogAddressConfig.cs
  31. 44 2
      Shaker/OilSource/OilSourceConfig.cs
  32. 2 4
      Shaker/Program.cs
  33. 2 4
      Shaker/Service.cs
  34. 1 1
      Shaker/ShakerFpga.cs
  35. 15 15
      Shaker/ShakerService.Control.cs
  36. 2 0
      Shaker/ShakerService.csproj
  37. 7 1
      Shaker/ViewModel/ServiceDataCacheViewModel.cs
  38. 13 4
      Shaker/ViewModel/ServiceRandomConfigViewModel.cs
  39. 3 1
      Shaker/ViewModel/ServiceShakerConfigViewModel.cs
  40. 1 2
      Shaker/ViewModel/ServiceShakerControlViewModel.cs
  41. 3 0
      Shaker/ViewModel/ServiceSineDataViewModel.cs
  42. 5 8
      ShakerControl.sln

+ 4 - 0
.editorconfig

@@ -0,0 +1,4 @@
+[*.cs]
+
+# RS1035: Do not use APIs banned for analyzers
+dotnet_diagnostic.RS1035.severity = none

+ 4 - 4
Avalonia/ShakerApp/ViewModels/MainPage/RandomMainPageViewModel.cs

@@ -97,17 +97,17 @@ namespace ShakerApp.ViewModels
             });
             GetEvent<AllConfig>().Subscrip((_, _) =>
             {
-                CommunicationViewModel.Instance.LocalCommunication?.GetEvent<RandomDataModel>().Subscrip((_, args) =>
+                CommunicationViewModel.Instance.LocalCommunication?.GetEvent<RandomDataModel>()?.Subscrip((_, args) =>
                 {
                     UpdateData(new List<IResultDataModel>() { args.Data });
-                    
+                    CommunicationViewModel.Instance.ServiceCommunication?.GetEvent<RandomDataModel>()?.Publish(this, args.Data);
                 });
-                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(nameof(RandomDataModel.TransferFunction)).Subscrip((sender, args) =>
+                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(nameof(RandomDataModel.TransferFunction))?.Subscrip((sender, args) =>
                 {
                     if (args.Data.Length > 0 && args.Data[0] is double[] func)
                     {
                         Tools.DispatherInovke.Inovke(()=> ShowTransferFunction(func));
-                        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(nameof(RandomDataModel.TransferFunction)).Publish(this, null, func);
+                        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(nameof(RandomDataModel.TransferFunction))?.Publish(this, null, func);
                     }
                 });
             });

+ 2 - 1
Avalonia/ShakerApp/ViewModels/MainPage/SineMainPageViewModel.cs

@@ -90,9 +90,10 @@ namespace ShakerApp.ViewModels
             });
             GetEvent<AllConfig>().Subscrip((_, _) =>
             {
-                CommunicationViewModel.Instance.LocalCommunication?.GetEvent<List<SineDataModel>>().Subscrip((_, args) =>
+                CommunicationViewModel.Instance.LocalCommunication?.GetEvent<List<SineDataModel>>()?.Subscrip((_, args) =>
                 {
                     UpdateData(args.Data.Cast<IResultDataModel>().ToList());
+                    CommunicationViewModel.Instance.ServiceCommunication?.GetEvent<List<SineDataModel>>()?.Publish(this, args.Data);
                 });
             });
         }

+ 79 - 53
Avalonia/ShakerApp/ViewModels/MainViewModel.cs

@@ -298,8 +298,8 @@ public class MainViewModel : ViewModelBase<IModel>
     }
     public void InitServiceMsg()
     {
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent<string>(Topic.SERVICERESULT).Subscrip((_, _) => Topic.SERVICERESULT);
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent<Shaker.Models.AllConfig>(Shaker.Models.Topic.SYNCCONFIG).Subscrip((_, _) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent<string>(Topic.SERVICERESULT)?.Subscrip((_, _) => Topic.SERVICERESULT);
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent<Shaker.Models.AllConfig>(Shaker.Models.Topic.SYNCCONFIG)?.Subscrip((_, _) =>
         {
             return new AllConfig()
             {
@@ -311,150 +311,176 @@ public class MainViewModel : ViewModelBase<IModel>
                 SweepConfig = SweepConfigViewModel.Instance.Model,
             };
         });
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent<DeviceInfoModel?>().Publish(this, ViewModels.DeviceMangerViewModel.Instance.CurrentDevice?.Model);
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent<RandomTestStep>().Subscrip((sender, args) =>
+
+
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent<ShakerConfigModel>()?.Subscrip((sender, args) =>
+        {
+            ShakerConfigViewModel.Instance.ReceiveServiceModel(args.Data);
+        });
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent<ShakerControlModel>()?.Subscrip((sender, args) =>
+        {
+            ShakerControlViewModel.Instance.ReceiveServiceModel(args.Data);
+        });
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent<SweepConfigModel>()?.Subscrip((sender, args) =>
+        {
+            SweepConfigViewModel.Instance.ReceiveServiceModel(args.Data);
+        });
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent<RandomConfigModel>()?.Subscrip((sender, args) =>
         {
-            CommunicationViewModel.Instance.LocalCommunication?.GetEvent<RandomTestStep>().Publish(this, args.Data);
+            RandomConfigViewModel.Instance.ReceiveServiceModel(args.Data);
         });
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent<MainPageType>().Subscrip((sender, args) =>
+
+
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent<DeviceInfoModel?>()?.Publish(this, ViewModels.DeviceMangerViewModel.Instance.CurrentDevice?.Model);
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent<RandomTestStep>()?.Subscrip((sender, args) =>
+        {
+            CommunicationViewModel.Instance.LocalCommunication?.GetEvent<RandomTestStep>()?.Publish(this, args.Data);
+        });
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent<MainPageType>()?.Subscrip((sender, args) =>
+        {
+            MainPageViewModel.Instance.MainPageType = args.Data;
+            CommunicationViewModel.Instance.LocalCommunication?.GetEvent<MainPageType>()?.Publish(this, args.Data);
+        });
+
+        CommunicationViewModel.Instance.LocalCommunication?.GetEvent<MainPageType>()?.Subscrip((sender, args) =>
         {
-            CommunicationViewModel.Instance.LocalCommunication?.GetEvent<MainPageType>().Publish(this, args.Data);
+            MainPageViewModel.Instance.MainPageType = args.Data;
         });
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Shaker.Models.Topic.START).Subscrip((_, _) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Shaker.Models.Topic.START)?.Subscrip((_, _) =>
         {
-            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.START).Publish(this);
+            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.START)?.Publish(this);
         });
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.STARTRANDOMTEST).Subscrip((_, _) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.STARTRANDOMTEST)?.Subscrip((_, _) =>
         {
-            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.STARTRANDOMTEST).Publish(this);
+            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.STARTRANDOMTEST)?.Publish(this);
         });
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.STOP).Subscrip((_, _) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.STOP)?.Subscrip((_, _) =>
         {
-            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.STOP).Publish(this);
+            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.STOP)?.Publish(this);
         });
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.RISETABLE).Subscrip((_, _) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.RISETABLE)?.Subscrip((_, _) =>
         {
-            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.RISETABLE).Publish(this);
+            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.RISETABLE)?.Publish(this);
         });
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.ZEROCHANGE).Subscrip((_, e) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.ZEROCHANGE)?.Subscrip((_, e) =>
         {
-            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.ZEROCHANGE).Publish(this, null, e.Data[0]);
+            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.ZEROCHANGE)?.Publish(this, null, e.Data[0]);
         });
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.DROPTABLE).Subscrip((_, _) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.DROPTABLE)?.Subscrip((_, _) =>
         {
-            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.DROPTABLE).Publish(this);
+            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.DROPTABLE)?.Publish(this);
         });
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.STOPSIGNALGEN).Subscrip((_, _) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.STOPSIGNALGEN)?.Subscrip((_, _) =>
         {
-            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.STOPSIGNALGEN).Publish(this);
+            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.STOPSIGNALGEN)?.Publish(this);
         });
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.VALVEPOWER).Subscrip((_, e) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.VALVEPOWER)?.Subscrip((_, e) =>
         {
-            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.STOPSIGNALGEN).Publish(this, null, e.Data[0]);
+            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.STOPSIGNALGEN)?.Publish(this, null, e.Data[0]);
         });
 
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.STARTSIGNALGEN).Subscrip((_, _) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.STARTSIGNALGEN)?.Subscrip((_, _) =>
         {
-            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.STARTSIGNALGEN).Publish(this);
+            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.STARTSIGNALGEN)?.Publish(this);
         });
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.RESETERROR).Subscrip((_, _) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.RESETERROR)?.Subscrip((_, _) =>
         {
-            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.RESETERROR).Publish(this);
+            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.RESETERROR)?.Publish(this);
         });
 
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.CircuitPressure).Subscrip((sender, args) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.CircuitPressure)?.Subscrip((sender, args) =>
         {
             if (args.Data.Length >= 2 && args.Data[0] is int index && args.Data[1] is float pressure)
             {
-                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CircuitPressure).Publish(this, null, index, pressure);
+                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CircuitPressure)?.Publish(this, null, index, pressure);
             }
         });
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.CircuitStart).Subscrip((sender, args) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.CircuitStart)?.Subscrip((sender, args) =>
         {
             if (args.Data.Length >= 2 && args.Data[0] is int index && args.Data[1] is bool state)
             {
-                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CircuitStart).Publish(this, null, index, state);
+                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CircuitStart)?.Publish(this, null, index, state);
             }
         });
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.CircuitLoad).Subscrip((sender, args) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.CircuitLoad)?.Subscrip((sender, args) =>
         {
             if (args.Data.Length >= 2 && args.Data[0] is int index && args.Data[1] is bool state)
             {
-                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CircuitLoad).Publish(this, null, index, state);
+                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CircuitLoad)?.Publish(this, null, index, state);
             }
         });
 
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.ForerunnerPressure).Subscrip((sender, args) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.ForerunnerPressure)?.Subscrip((sender, args) =>
         {
             if (args.Data.Length >= 1 && args.Data[0] is float pressure)
             {
-                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.ForerunnerPressure).Publish(this, null, pressure);
+                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.ForerunnerPressure)?.Publish(this, null, pressure);
             }
         });
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.ForerunnerStart).Subscrip((sender, args) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.ForerunnerStart)?.Subscrip((sender, args) =>
         {
             if (args.Data.Length >= 1 && args.Data[0] is bool state)
             {
-                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.ForerunnerStart).Publish(this, null, state);
+                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.ForerunnerStart)?.Publish(this, null, state);
             }
         });
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.ForerunnerLoad).Subscrip((sender, args) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.ForerunnerLoad)?.Subscrip((sender, args) =>
         {
             if (args.Data.Length >= 1 && args.Data[0] is bool state)
             {
-                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.ForerunnerLoad).Publish(this, null, state);
+                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.ForerunnerLoad)?.Publish(this, null, state);
             }
         });
 
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.AssistantPressure).Subscrip((sender, args) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.AssistantPressure)?.Subscrip((sender, args) =>
         {
             if (args.Data.Length >= 1 && args.Data[0] is float pressure)
             {
-                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.AssistantPressure).Publish(this, null, pressure);
+                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.AssistantPressure)?.Publish(this, null, pressure);
             }
         });
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.AssistantStart).Subscrip((sender, args) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.AssistantStart)?.Subscrip((sender, args) =>
         {
             if (args.Data.Length >= 1 && args.Data[0] is bool state)
             {
-                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.AssistantStart).Publish(this, null, state);
+                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.AssistantStart)?.Publish(this, null, state);
             }
         });
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.AssistantLoad).Subscrip((sender, args) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.AssistantLoad)?.Subscrip((sender, args) =>
         {
             if (args.Data.Length >= 1 && args.Data[0] is bool state)
             {
-                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.AssistantLoad).Publish(this, null, state);
+                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.AssistantLoad)?.Publish(this, null, state);
             }
         });
 
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.CirculatePressure).Subscrip((sender, args) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.CirculatePressure)?.Subscrip((sender, args) =>
         {
             if (args.Data.Length >= 1 && args.Data[0] is float pressure)
             {
-                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CirculatePressure).Publish(this, null, pressure);
+                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CirculatePressure)?.Publish(this, null, pressure);
             }
         });
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.CirculateStart).Subscrip((sender, args) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.CirculateStart)?.Subscrip((sender, args) =>
         {
             if (args.Data.Length >= 1 && args.Data[0] is bool state)
             {
-                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CirculateStart).Publish(this, null, state);
+                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CirculateStart)?.Publish(this, null, state);
             }
         });
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.CirculateLoad).Subscrip((sender, args) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.CirculateLoad)?.Subscrip((sender, args) =>
         {
             if (args.Data.Length >= 1 && args.Data[0] is bool state)
             {
-                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CirculateLoad).Publish(this, null, state);
+                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CirculateLoad)?.Publish(this, null, state);
             }
         });
 
-        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.OilEmergencyStop).Subscrip((sender, args) =>
+        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.OilEmergencyStop)?.Subscrip((sender, args) =>
         {
             if (args.Data.Length >= 1 && args.Data[0] is bool state)
             {
-                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.OilEmergencyStop).Publish(this, null, state);
+                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.OilEmergencyStop)?.Publish(this, null, state);
             }
         });
     }

+ 15 - 15
Avalonia/ShakerApp/ViewModels/Oil/OilSourceStatusViewModel.cs

@@ -41,7 +41,7 @@ namespace ShakerApp.ViewModels
                     UpDateModel(args.Data);
                     CommunicationViewModel.Instance.ServiceCommunication?.GetEvent<OilSourceStatusModel>()?.Publish(this, args.Data);
                 });
-                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.OilStatusChanged).Subscrip((sender, args) =>
+                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.OilStatusChanged)?.Subscrip((sender, args) =>
                 {
                     if(args.Data.Length>=1 && args.Data[0] is bool state)
                     {
@@ -55,7 +55,7 @@ namespace ShakerApp.ViewModels
                             MainViewModel.Default.ShowToast(msg, Avalonia.Controls.Notifications.NotificationType.Error);
                         }
                         LogViewModel.Instance.AddLog(msg,state ? LogType.Info : LogType.Error);
-                        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.OilStatusChanged).Publish(this,null, state);
+                        CommunicationViewModel.Instance.ServiceCommunication?.GetEvent(Topic.OilStatusChanged)?.Publish(this,null, state);
                     }
                 });
             });
@@ -66,7 +66,7 @@ namespace ShakerApp.ViewModels
         }
         public void EmergencyStop()
         {
-            CommunicationViewModel.Instance.LocalCommunication.GetEvent(Topic.OilEmergencyStop).Publish(this, null, true);
+            CommunicationViewModel.Instance.LocalCommunication.GetEvent(Topic.OilEmergencyStop)?.Publish(this, null, false);
         }
         public override bool CanCancel => false;
         public static OilSourceStatusViewModel Instance { get; } = new OilSourceStatusViewModel();
@@ -74,9 +74,9 @@ namespace ShakerApp.ViewModels
 
         public CircuitViewModel Circulate { get; } = new CircuitViewModel()
         {
-            PressureAction = (pressure) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CirculatePressure).Publish(OilSourceStatusViewModel.Instance.Forerunner, null, pressure),
-            StartAction = (state) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CirculateStart).Publish(OilSourceStatusViewModel.Instance.Forerunner, null, state),
-            LoadAction = (state) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CirculateLoad).Publish(OilSourceStatusViewModel.Instance.Forerunner, null, state)
+            PressureAction = (pressure) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CirculatePressure)?.Publish(OilSourceStatusViewModel.Instance.Forerunner, null, pressure),
+            StartAction = (state) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CirculateStart)?.Publish(OilSourceStatusViewModel.Instance.Forerunner, null, state),
+            LoadAction = (state) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CirculateLoad)?.Publish(OilSourceStatusViewModel.Instance.Forerunner, null, state)
         };
         [PropertyAssociation(nameof(OilSourceStatusModel.IsRemote))]
         public bool IsRemote
@@ -97,9 +97,9 @@ namespace ShakerApp.ViewModels
         /// </summary>
         public CircuitViewModel Forerunner { get; } = new CircuitViewModel()
         {
-            PressureAction = (pressure)=> CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.ForerunnerPressure).Publish(OilSourceStatusViewModel.Instance.Forerunner, null, pressure),
-            StartAction = (state) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.ForerunnerStart).Publish(OilSourceStatusViewModel.Instance.Forerunner, null, state),
-            LoadAction = (state) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.ForerunnerLoad).Publish(OilSourceStatusViewModel.Instance.Forerunner, null, state)
+            PressureAction = (pressure)=> CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.ForerunnerPressure)?.Publish(OilSourceStatusViewModel.Instance.Forerunner, null, pressure),
+            StartAction = (state) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.ForerunnerStart)?.Publish(OilSourceStatusViewModel.Instance.Forerunner, null, state),
+            LoadAction = (state) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.ForerunnerLoad)?.Publish(OilSourceStatusViewModel.Instance.Forerunner, null, state)
         };
         /// <summary>
         /// 主油路
@@ -109,9 +109,9 @@ namespace ShakerApp.ViewModels
 
         public CircuitViewModel Assistant { get; } = new CircuitViewModel()
         {
-            PressureAction = (pressure) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.AssistantPressure).Publish(OilSourceStatusViewModel.Instance.Forerunner, null, pressure),
-            StartAction = (state) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.AssistantStart).Publish(OilSourceStatusViewModel.Instance.Forerunner, null, state),
-            LoadAction = (state) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.AssistantLoad).Publish(OilSourceStatusViewModel.Instance.Forerunner, null, state)
+            PressureAction = (pressure) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.AssistantPressure)?.Publish(OilSourceStatusViewModel.Instance.Forerunner, null, pressure),
+            StartAction = (state) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.AssistantStart)?.Publish(OilSourceStatusViewModel.Instance.Forerunner, null, state),
+            LoadAction = (state) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.AssistantLoad)?.Publish(OilSourceStatusViewModel.Instance.Forerunner, null, state)
         };
 
         public AvaloniaList<OilErrorInfoViewModel> OilErrors { get; } = new AvaloniaList<OilErrorInfoViewModel>();
@@ -142,9 +142,9 @@ namespace ShakerApp.ViewModels
                 for (int i = 0; i < model.Circuit.Count; i++)
                 {
                     Circuit[i].Value?.UpDateModel(model.Circuit[i]);
-                    Circuit[i].Value.StartAction = (state) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CircuitStart).Publish(this, null,i, state);
-                    Circuit[i].Value.LoadAction = (state) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CircuitLoad).Publish(this, null,i, state);
-                    Circuit[i].Value.PressureAction = (pressure) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CircuitPressure).Publish(this, null,i, pressure);
+                    Circuit[i].Value.StartAction = (state) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CircuitStart)?.Publish(this, null,i, state);
+                    Circuit[i].Value.LoadAction = (state) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CircuitLoad)?.Publish(this, null,i, state);
+                    Circuit[i].Value.PressureAction = (pressure) => CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.CircuitPressure)?.Publish(this, null,i, pressure);
                 }
             }
             Assistant?.UpDateModel(model.Assistant);

+ 0 - 4
Avalonia/ShakerApp/ViewModels/ShakerConfig/RandomConfigViewModel.cs

@@ -163,10 +163,6 @@ namespace ShakerApp.ViewModels
             GetEvent<AllConfig>().Subscrip((sender, args) =>
             {
                 UpDateModel(args.Data.RandomConfig);
-                if (CommunicationViewModel.Instance.ServiceIsStart)
-                {
-                    CommunicationViewModel.Instance.ServiceCommunication.GetEvent<RandomConfigModel>().Publish(this, args.Data.RandomConfig);
-                }
                 CommunicationViewModel.Instance.LocalCommunication?.GetEvent<RandomConfigModel>()?.Subscrip((sender, args) =>
                 {
                     UpDateModel(args.Data);

+ 7 - 4
Avalonia/ShakerApp/ViewModels/ShakerConfig/ShakerConfigViewModel.cs

@@ -11,6 +11,8 @@ namespace ShakerApp.ViewModels
 {
     internal class ShakerConfigViewModel : ViewModelBase<Shaker.Models.ShakerConfigModel>
     {
+        [PropertyAssociation(nameof(ShakerConfigModel.DisplacementBias))]
+        public float DisplacementBias { get => Model.DisplacementBias; set => SetProperty(ref Model.DisplacementBias, value); }
         [PropertyAssociation(nameof(ShakerConfigModel.SynthesisType))]
         public AccelerationSynthesisType SynthesisType { get => Model.SynthesisType; set => SetProperty(ref Model.SynthesisType, value); }
         [PropertyAssociation(nameof(ShakerConfigModel.OutSignalGain))]
@@ -107,10 +109,6 @@ namespace ShakerApp.ViewModels
             {
                 UpDateModel(args.Data.ShakerConfig);
                 OnPropertyChanged(nameof(AccelerationSensorCount));
-                if(CommunicationViewModel.Instance.ServiceIsStart)
-                {
-                    CommunicationViewModel.Instance.ServiceCommunication.GetEvent<Shaker.Models.ShakerConfigModel>().Publish(this, args.Data.ShakerConfig);
-                }
                 CommunicationViewModel.Instance.LocalCommunication?.GetEvent<Shaker.Models.ShakerConfigModel>()?.Subscrip((sender, args) =>
                 {
                     if (args.Data == null) return;
@@ -155,6 +153,11 @@ namespace ShakerApp.ViewModels
             CommunicationViewModel.Instance.LocalCommunication?.GetEvent<Shaker.Models.ShakerConfigModel>()?.Publish(this, Model);
             CommunicationViewModel.Instance.ServiceCommunication?.GetEvent<Shaker.Models.ShakerConfigModel>()?.Publish(this, Model);
         }
+        public override void ReceiveServiceModel(ShakerConfigModel model)
+        {
+            base.ReceiveServiceModel(model);
+            CommunicationViewModel.Instance.LocalCommunication?.GetEvent<Shaker.Models.ShakerConfigModel>()?.Publish(this, Model);
+        }
     }
 }
 

+ 0 - 4
Avalonia/ShakerApp/ViewModels/ShakerConfig/SweepConfigViewModel.cs

@@ -177,10 +177,6 @@ namespace ShakerApp.ViewModels
             GetEvent<AllConfig>().Subscrip((sender, args) =>
             {
                 UpDateModel(args.Data.SweepConfig);
-                if(CommunicationViewModel.Instance.ServiceIsStart)
-                {
-                    CommunicationViewModel.Instance.ServiceCommunication.GetEvent<SweepConfigModel>().Publish(this, args.Data.SweepConfig);
-                }
                 CommunicationViewModel.Instance.LocalCommunication?.GetEvent<SweepConfigModel>()?.Subscrip((sender, args) =>
                 {
                     UpDateModel(args.Data);

+ 4 - 6
Avalonia/ShakerApp/ViewModels/ShakerControl/ShakerControlViewModel.cs

@@ -28,10 +28,6 @@ namespace ShakerApp.ViewModels
             GetEvent<AllConfig>().Subscrip((sender, args) =>
             {
                 UpDateModel(args.Data.ShakerControl);
-                if(CommunicationViewModel.Instance.ServiceIsStart)
-                {
-                    CommunicationViewModel.Instance.ServiceCommunication.GetEvent<ShakerControlModel>().Publish(this, args.Data.ShakerControl);
-                }
                 CommunicationViewModel.Instance.LocalCommunication?.GetEvent<ShakerControlModel>()?.Subscrip((sender, args) =>
                 {
                     UpDateModel(args.Data);
@@ -68,8 +64,11 @@ namespace ShakerApp.ViewModels
             get => Model.PageType;
             set
             {
+                bool changed = Model.PageType != value;
                 SetProperty(ref Model.PageType, value);
+                if (!changed) return;
                 CommunicationViewModel.Instance.LocalCommunication?.GetEvent<MainPageType>()?.Publish(this, value);
+                CommunicationViewModel.Instance.ServiceCommunication?.GetEvent<MainPageType>()?.Publish(this, value);
             }
         }
         [PropertyAssociation(nameof(ShakerControlModel.MaxControlItemCount))]
@@ -100,8 +99,7 @@ namespace ShakerApp.ViewModels
         public int ServoValveCount => Model.ValveConfig.Count;
         [PropertyAssociation(nameof(ShakerControlModel.MaxDisplacementIntegral))]
         public float MaxDisplacementIntegral { get => Model.MaxDisplacementIntegral; set => SetProperty(ref Model.MaxDisplacementIntegral, value); }
-        [PropertyAssociation(nameof(ShakerControlModel.DisplacementBias))]
-        public float DisplacementBias { get => Model.DisplacementBias; set => SetProperty(ref Model.DisplacementBias, value); }
+
         [PropertyAssociation(nameof(ShakerControlModel.ValveConfig))]
         public ObservableCollection<IndexValueItemViewModel<ValveConfigItemViewModel>> ValveConfig { get; } = new ObservableCollection<IndexValueItemViewModel<ValveConfigItemViewModel>>();
         [PropertyAssociation(nameof(ShakerControlModel.OilStopped))]

+ 10 - 14
Avalonia/ShakerApp/ViewModels/ShakerStatus/ShakerStatusViewModel.cs

@@ -101,7 +101,7 @@ namespace ShakerApp.ViewModels
             set
             {
                 SetProperty(ref workPosition, value);
-                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.ZEROCHANGE).Publish(this, null, value);
+                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.ZEROCHANGE)?.Publish(this, null, value);
             }
         }
         private ShakerStatusViewModel()
@@ -112,10 +112,6 @@ namespace ShakerApp.ViewModels
             {
                 valvePower = false;
                 UpDateModel(args.Data.ShakerStatus);
-                if(CommunicationViewModel.Instance.ServiceIsStart)
-                {
-                    CommunicationViewModel.Instance.ServiceCommunication.GetEvent<ShakerStatusModel>().Publish(this, args.Data.ShakerStatus);
-                }
                 CommunicationViewModel.Instance.LocalCommunication?.GetEvent<ShakerStatusModel>()?.Subscrip((sender, args) =>
                 {
                     UpDateModel(args.Data);
@@ -156,17 +152,17 @@ namespace ShakerApp.ViewModels
         public ICommand RiseTableCommand => new RelayCommand(RiseTableCommandExecute);
         private void RiseTableCommandExecute()
         {
-            CommunicationViewModel.Instance.LocalCommunication.GetEvent(Topic.RISETABLE).Publish(this, null);
+            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.RISETABLE)?.Publish(this, null);
         }
         public ICommand DropTableCommand => new RelayCommand(DropTableCommandExecute);
         private void DropTableCommandExecute()
         {
-            CommunicationViewModel.Instance.LocalCommunication.GetEvent(Topic.DROPTABLE).Publish(this, null);
+            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.DROPTABLE)?.Publish(this, null);
         }
         public ICommand ResetCommand => new RelayCommand(Reset);
         private void Reset()
         {
-            CommunicationViewModel.Instance.LocalCommunication.GetEvent(Topic.RESETERROR).Publish(this, null);
+            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.RESETERROR)?.Publish(this, null);
         }
 
         public ICommand EmergencyStopCommand => new RelayCommand(EmergencyStopCommandExecute);
@@ -182,20 +178,20 @@ namespace ShakerApp.ViewModels
             {
                 case MainPageType.SinePage:
                     SineMainPageViewModel.Instance.Start();
-                    CommunicationViewModel.Instance.LocalCommunication.GetEvent<MainPageType>().Publish(this, MainPageType.SinePage);
+                    CommunicationViewModel.Instance.LocalCommunication?.GetEvent<MainPageType>()?.Publish(this, MainPageType.SinePage);
                     break;
                 case MainPageType.RandomPage:
-                    CommunicationViewModel.Instance.LocalCommunication.GetEvent<RandomTestStep>().Publish(this, RandomTestStep.Start);
-                    CommunicationViewModel.Instance.LocalCommunication.GetEvent<MainPageType>().Publish(this, MainPageType.RandomPage);
+                    CommunicationViewModel.Instance.LocalCommunication?.GetEvent<RandomTestStep>()?.Publish(this, RandomTestStep.Start);
+                    CommunicationViewModel.Instance.LocalCommunication?.GetEvent<MainPageType>()?.Publish(this, MainPageType.RandomPage);
                     RandomMainPageViewModel.Instance.Start();
                     break;
             }
-            CommunicationViewModel.Instance.LocalCommunication.GetEvent(Topic.STARTSIGNALGEN).Publish(this, null);
+            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.STARTSIGNALGEN)?.Publish(this, null);
         }
         public ICommand StopCommand => new RelayCommand(StopCommandExecute);
         private void StopCommandExecute()
         {
-            CommunicationViewModel.Instance.LocalCommunication.GetEvent(Topic.STOPSIGNALGEN).Publish(this, null);
+            CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.STOPSIGNALGEN)?.Publish(this, null);
         }
 
         public static ShakerStatusViewModel Instance { get; } = new ShakerStatusViewModel();
@@ -208,7 +204,7 @@ namespace ShakerApp.ViewModels
             {
                 //if (valvePower == value) return;
                 SetProperty(ref valvePower, value);
-                CommunicationViewModel.Instance.LocalCommunication.GetEvent(Topic.VALVEPOWER).Publish(this, null, value);
+                CommunicationViewModel.Instance.LocalCommunication?.GetEvent(Topic.VALVEPOWER)?.Publish(this, null, value);
             }
         }
     }

+ 10 - 0
Avalonia/ShakerApp/ViewModels/ViewModelBase.cs

@@ -133,6 +133,16 @@ public abstract class ViewModelBase<TModel> : ObservableObject where TModel : IM
         UpDateModel(model);
     }
 
+
+    public virtual void ReceiveServiceModel(TModel model)
+    {
+        if (typeof(TModel).IsAbstract || typeof(TModel).IsInterface) return;
+        if(lastModel!=null)
+        {
+            lastModel = (TModel)model.Clone();
+        }
+        UpDateModel(model);
+    }
     public virtual void UpDateModel(TModel model)
     {
         if (typeof(TModel).IsAbstract || typeof(TModel).IsInterface) return;

+ 1 - 1
Avalonia/ShakerApp/Views/ShakerConfig/ShakerConfigView.axaml

@@ -63,7 +63,7 @@
                                     <NumericUpDown
                                         Width="120"
                                         Margin="4,0,0,0"
-                                        Value="{Binding Source={x:Static vm:ShakerControlViewModel.Instance}, Path=DisplacementBias}" />
+                                        Value="{Binding DisplacementBias}" />
                                     <TextBlock
                                         Margin="4,0,0,0"
                                         VerticalAlignment="Center"

+ 22 - 15
Calc/FFTW/DFT.cs

@@ -137,21 +137,28 @@ namespace FFTW.NET
 				plan.Execute();
 			}
 		}
-
-		public static double[] FFT(double[] data)
-		{
-			if (data == null || data.Length == 0) return data;
-			var input = new PinnedArray<Complex>(data.Select(x => new Complex(x, 0)).ToArray());
-			var output = new PinnedArray<Complex>(new Complex[data.Length]);
-			FFT(input, output);
-			return output.Buffer.Cast<Complex>().Select(x => x.Real).ToArray();
-		}
-		/// <summary>
-		/// Performs a complex-to-real inverse fast fourier transformation.
-		/// </summary>
-		/// <seealso cref="http://www.fftw.org/fftw3_doc/One_002dDimensional-DFTs-of-Real-Data.html#One_002dDimensional-DFTs-of-Real-Data"/>
-		/// <seealso cref="http://www.fftw.org/fftw3_doc/Multi_002dDimensional-DFTs-of-Real-Data.html#Multi_002dDimensional-DFTs-of-Real-Data"/>
-		public static void IFFT(IPinnedArray<Complex> input, IPinnedArray<double> output, PlannerFlags plannerFlags = PlannerFlags.Default, int nThreads = 1)
+        public static Complex[] IFFT(double[] data, double[] img)
+        {
+            if (data == null || data.Length == 0 || img == null || img.Length != data.Length) return new Complex[0];
+            var input = new PinnedArray<Complex>(Enumerable.Range(0, data.Length).Select(x => new Complex(data[x], img[x])).ToArray());
+            var output = new PinnedArray<Complex>(new Complex[data.Length]);
+            IFFT(input, output);
+            return output.Buffer.Cast<Complex>().ToArray();
+        }
+        public static Complex[] FFT(double[] data, double[] img)
+        {
+            if (data == null || data.Length == 0 || img == null || img.Length != data.Length) return new Complex[0];
+			var input = new PinnedArray<Complex>(Enumerable.Range(0, data.Length).Select(x => new Complex(data[x], img[x])).ToArray());
+            var output = new PinnedArray<Complex>(new Complex[data.Length]);
+            FFT(input, output);
+            return output.Buffer.Cast<Complex>().ToArray();
+        }
+        /// <summary>
+        /// Performs a complex-to-real inverse fast fourier transformation.
+        /// </summary>
+        /// <seealso cref="http://www.fftw.org/fftw3_doc/One_002dDimensional-DFTs-of-Real-Data.html#One_002dDimensional-DFTs-of-Real-Data"/>
+        /// <seealso cref="http://www.fftw.org/fftw3_doc/Multi_002dDimensional-DFTs-of-Real-Data.html#Multi_002dDimensional-DFTs-of-Real-Data"/>
+        public static void IFFT(IPinnedArray<Complex> input, IPinnedArray<double> output, PlannerFlags plannerFlags = PlannerFlags.Default, int nThreads = 1)
 		{
 			if ((plannerFlags & PlannerFlags.Estimate) == PlannerFlags.Estimate)
 			{

+ 1 - 2
Calc/FFTW/FftwInterop.cs

@@ -97,13 +97,12 @@ namespace FFTW.NET
             else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
             {
                 _NativeLoader = new NativeLibraryLoader.NativeLoader(linuxdllname);
-                _NativeLoader.SearchDirectories.Add("/usr/lib/x86_64-linux-gnu/");
-                _NativeLoader.SearchDirectories.Add("/usr/lib/");
             }
             else
             {
                 throw new PlatformNotSupportedException();
             }
+			_NativeLoader.SearchDirectories.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "libs"));
             _NativeLoader.Init();
 			_version = GetVersionAndInitialize();
         }

+ 1 - 1
Calc/FFTW/FftwPlan.cs

@@ -59,7 +59,7 @@ namespace FFTW.NET
 
 			lock (FftwInterop.Lock)
 			{
-				FftwInterop.GetDelegate<FftwInterop.fftw_plan_with_nthreads>()(nThreads);
+				//FftwInterop.GetDelegate<FftwInterop.fftw_plan_with_nthreads>()(nThreads);
 				_plan = GetPlan(rank, n, _buffer1.Pointer, _buffer2.Pointer, direction, plannerFlags);
 			}
 		}

+ 3 - 1
Calc/FxpConvert.Common/ICalc.cs

@@ -45,7 +45,9 @@ namespace FxpConvert.Common
     public interface IFFT
     {
         public void FFT(double[] real, double[] imaginary);
-        public void FFT(float[] real, float[] imaginary);
+        public void FFT(float[] real, float[] imaginary); 
+        public void IFFT(double[] real, double[] imaginary);
+        public void IFFT(float[] real, float[] imaginary);
     }
     public interface IAdd
     {

+ 32 - 2
Calc/SIMDFxpConvert/SIMDCalc.cs

@@ -165,16 +165,46 @@ namespace SIMDFxpConvert
     }
     public sealed class SIMDFFT : IFFT
     {
+        public SIMDFFT()
+        {
+            FFTW.NET.FftwInterop.Initialize();
+        }
         public void FFT(double[] real, double[] imaginary)
         {
-            MathNet.Numerics.IntegralTransforms.Fourier.Forward(real,imaginary, MathNet.Numerics.IntegralTransforms.FourierOptions.Matlab);
+            var result = FFTW.NET.DFT.FFT(real, imaginary);
+            var tempreal = result.Select(x => x.Real).ToArray();
+            var tempimg = result.Select(x => x.Imaginary).ToArray();
+            Unsafe.CopyBlock(ref Unsafe.As<double, byte>(ref real[0]), ref Unsafe.As<double, byte>(ref tempreal[0]), (uint)(real.Length * Unsafe.SizeOf<double>()));
+            Unsafe.CopyBlock(ref Unsafe.As<double, byte>(ref imaginary[0]), ref Unsafe.As<double, byte>(ref tempimg[0]), (uint)(real.Length * Unsafe.SizeOf<double>()));
 
         }
         public void FFT(float[] real, float[] imaginary)
         {
-            MathNet.Numerics.IntegralTransforms.Fourier.Forward(real,imaginary, MathNet.Numerics.IntegralTransforms.FourierOptions.Matlab);
+            var result = FFTW.NET.DFT.FFT(real.Select(x=> (double)x).ToArray(), imaginary.Select(x=> (double)x).ToArray());
+
+            var tempreal = result.Select(x => (float)x.Real).ToArray();
+            var tempimg = result.Select(x => (float)x.Imaginary).ToArray();
+            Unsafe.CopyBlock(ref Unsafe.As<float, byte>(ref real[0]), ref Unsafe.As<float, byte>(ref tempreal[0]), (uint)(real.Length * Unsafe.SizeOf<float>()));
+            Unsafe.CopyBlock(ref Unsafe.As<float, byte>(ref imaginary[0]), ref Unsafe.As<float, byte>(ref tempimg[0]), (uint)(real.Length * Unsafe.SizeOf<float>()));
+        }
+        public void IFFT(double[] real, double[] imaginary)
+        {
+            var result = FFTW.NET.DFT.IFFT(real, imaginary);
+            var tempreal = result.Select(x => x.Real).ToArray();
+            var tempimg = result.Select(x => x.Imaginary).ToArray();
+            Unsafe.CopyBlock(ref Unsafe.As<double, byte>(ref real[0]), ref Unsafe.As<double, byte>(ref tempreal[0]), (uint)(real.Length * Unsafe.SizeOf<double>()));
+            Unsafe.CopyBlock(ref Unsafe.As<double, byte>(ref imaginary[0]), ref Unsafe.As<double, byte>(ref tempimg[0]), (uint)(real.Length * Unsafe.SizeOf<double>()));
+
         }
+        public void IFFT(float[] real, float[] imaginary)
+        {
+            var result = FFTW.NET.DFT.IFFT(real.Select(x => (double)x).ToArray(), imaginary.Select(x => (double)x).ToArray());
 
+            var tempreal = result.Select(x => (float)x.Real).ToArray();
+            var tempimg = result.Select(x => (float)x.Imaginary).ToArray();
+            Unsafe.CopyBlock(ref Unsafe.As<float, byte>(ref real[0]), ref Unsafe.As<float, byte>(ref tempreal[0]), (uint)(real.Length * Unsafe.SizeOf<float>()));
+            Unsafe.CopyBlock(ref Unsafe.As<float, byte>(ref imaginary[0]), ref Unsafe.As<float, byte>(ref tempimg[0]), (uint)(real.Length * Unsafe.SizeOf<float>()));
+        }
     }
     public unsafe sealed class SIMDAdd : IAdd
     {

+ 9 - 2
Calc/SIMDFxpConvert/SIMDFxpConvert.csproj

@@ -14,8 +14,15 @@
   <Import Project="..\..\NativeLoader\NativeLoader.projitems" Label="Shared" />
 
   <ItemGroup>
-    <PackageReference Include="MathNet.Numerics" Version="6.0.0-beta1" />
-    <PackageReference Include="MathNet.Numerics.Providers.OpenBLAS" Version="6.0.0-beta1" />
+    <None Update="libs\libfftw3-3-x64.dll">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="libs\libfftw3-3-x86.dll">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
+    <None Update="libs\libfftw3.so">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
   </ItemGroup>
 
 </Project>

BIN
Calc/SIMDFxpConvert/libs/libfftw3-3-x64.dll


BIN
Calc/SIMDFxpConvert/libs/libfftw3-3-x86.dll


BIN
Calc/SIMDFxpConvert/libs/libfftw3.so


+ 4 - 4
Communication/ActiveMQCommunication/Communication.cs

@@ -52,7 +52,7 @@ namespace ActiveMQCommunication
             
         }
 
-        public IEventData<TData> GetEvent<TData>()
+        public IEventData<TData>? GetEvent<TData>()
         {
             lock (_list)
             {
@@ -72,7 +72,7 @@ namespace ActiveMQCommunication
             }
         }
 
-        public IEventData<TData, T> GetEvent<TData, T>()
+        public IEventData<TData, T>? GetEvent<TData, T>()
         {
             lock (_list)
             {
@@ -92,7 +92,7 @@ namespace ActiveMQCommunication
             }
         }
 
-        public IAnonymousEventData GetEvent(string eventName)
+        public IAnonymousEventData? GetEvent(string eventName)
         {
             lock (_list)
             {
@@ -113,7 +113,7 @@ namespace ActiveMQCommunication
             }
         }
 
-        public IAnonymousEventData<T> GetEvent<T>(string eventName)
+        public IAnonymousEventData<T>? GetEvent<T>(string eventName)
         {
             lock (_list)
             {

+ 8 - 8
Communication/LocalCommunication/Communication.cs

@@ -31,24 +31,24 @@ namespace LocalCommunication
             eventBus.Disconnected += (_, _) => this.Disconnected?.Invoke(this, EventArgs.Empty);
         }
 
-        public IEventData<TData> GetEvent<TData>()
+        public IEventData<TData>? GetEvent<TData>()
         {
-            return eventBus.GetEvent<TData>();
+            return eventBus?.GetEvent<TData>();
         }
 
-        public IEventData<TData, T> GetEvent<TData, T>()
+        public IEventData<TData, T>? GetEvent<TData, T>()
         {
-            return eventBus.GetEvent<TData, T>();
+            return eventBus?.GetEvent<TData, T>();
         }
 
-        public IAnonymousEventData GetEvent(string eventName)
+        public IAnonymousEventData? GetEvent(string eventName)
         {
-            return eventBus.GetEvent(eventName);
+            return eventBus?.GetEvent(eventName);
         }
 
-        public IAnonymousEventData<T> GetEvent<T>(string eventName)
+        public IAnonymousEventData<T>? GetEvent<T>(string eventName)
         {
-            return eventBus.GetEvent<T>(eventName);
+            return eventBus?.GetEvent<T>(eventName);
         }
 
         public void Start()

+ 4 - 4
EventBroker/EventBroker.Common/IEventBroker.cs

@@ -7,26 +7,26 @@
         /// </summary>
         /// <typeparam name="TData">数据类型</typeparam>
         /// <returns>事件句柄</returns>
-        IEventData<TData> GetEvent<TData>();
+        IEventData<TData>? GetEvent<TData>();
         /// <summary>
         /// 根据TData数据类型获取带返回值的事件句柄
         /// </summary>
         /// <typeparam name="TData">数据类型</typeparam>
         /// <typeparam name="T">返回数据类型</typeparam>
         /// <returns>事件句柄</returns>
-        IEventData<TData, T> GetEvent<TData, T>();
+        IEventData<TData, T>? GetEvent<TData, T>();
         /// <summary>
         /// 根据<paramref name="eventName"/>获取事件句柄
         /// </summary>
         /// <param name="eventName">事件名称</param>
         /// <returns>事件句柄</returns>
-        IAnonymousEventData GetEvent(string eventName);
+        IAnonymousEventData? GetEvent(string eventName);
         /// <summary>
         /// 根据<paramref name="eventName"/>获取事件句柄
         /// </summary>
         /// <param name="eventName">事件名称</param>
         /// <typeparam name="T">返回数据类型</typeparam>
         /// <returns>事件句柄</returns>
-        IAnonymousEventData<T> GetEvent<T>(string eventName);
+        IAnonymousEventData<T>? GetEvent<T>(string eventName);
     }
 }

+ 1 - 0
Shaker.Model/Models/ShakerConfigModel.cs

@@ -2,6 +2,7 @@
 {
     public class ShakerConfigModel : BaseModel
     {
+        public float DisplacementBias = 0;
         public AccelerationSynthesisType SynthesisType = AccelerationSynthesisType.Synthesis; 
         public double OutSignalGain = 1;
         public uint MaxRiseCount = 120000;

+ 0 - 1
Shaker.Model/Models/ShakerControlModel.cs

@@ -18,7 +18,6 @@ namespace Shaker.Models
         public float FlutterAmpt = 0.01f;
         public float MaxDisplacementIntegral = 2;
         public MainPageType PageType = MainPageType.StartPage;
-        public float DisplacementBias = 0;
         public List<ValveConfigItemModel> ValveConfig = new List<ValveConfigItemModel>();
 
         public bool OilStopped = false;

+ 20 - 20
Shaker/ClassDiagram1.cd

@@ -29,7 +29,7 @@
       <FileName>ViewModel\ServiceAccelerationConfigViewModel.cs</FileName>
     </TypeIdentifier>
   </Class>
-  <Class Name="ShakerService.ViewModel.ServiceAnalogSignalConfigViewModel" Collapsed="true">
+  <Class Name="ShakerService.ViewModel.ServiceAnalogSignalConfigViewModel">
     <Position X="36" Y="1.75" Width="1.5" />
     <TypeIdentifier>
       <HashCode>AAAAAAAAAAAABAAAIAAAAAQAAAAAAAAAAAAAAAAAAAA=</HashCode>
@@ -65,14 +65,14 @@
       <FileName>ViewModel\ServiceRandomPlanItemViewModel.cs</FileName>
     </TypeIdentifier>
   </Class>
-  <Class Name="ShakerService.ViewModel.ServiceRandomSpectralTableViewModel" Collapsed="true">
+  <Class Name="ShakerService.ViewModel.ServiceRandomSpectralTableViewModel">
     <Position X="38.25" Y="1.75" Width="1.5" />
     <TypeIdentifier>
       <HashCode>AgAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAEAgAAAAAA=</HashCode>
       <FileName>ViewModel\ServiceRandomSpectralTableViewModel.cs</FileName>
     </TypeIdentifier>
   </Class>
-  <Class Name="ShakerService.ViewModel.ServiceRandomSpectrumItemViewModel" Collapsed="true">
+  <Class Name="ShakerService.ViewModel.ServiceRandomSpectrumItemViewModel">
     <Position X="4.5" Y="1.75" Width="1.5" />
     <TypeIdentifier>
       <HashCode>AAAAAAAAAAQAAAAAAAAAAAAAAIAAMAAAEAAgAAAAEAA=</HashCode>
@@ -82,14 +82,14 @@
   <Class Name="ShakerService.ViewModel.ServiceShakerConfigViewModel" Collapsed="true">
     <Position X="11.25" Y="1.75" Width="1.5" />
     <TypeIdentifier>
-      <HashCode>hgCCAAAUQEAEKCACARBCAAAQCEkCJAAgwEEABIAQAQA=</HashCode>
+      <HashCode>hgCCAAAUQEAEKCACARBCAAAQCEkCJAEgwEEABIAQAQA=</HashCode>
       <FileName>ViewModel\ServiceShakerConfigViewModel.cs</FileName>
     </TypeIdentifier>
   </Class>
   <Class Name="ShakerService.ViewModel.ServiceShakerControlViewModel" Collapsed="true">
     <Position X="18" Y="1.75" Width="1.5" />
     <TypeIdentifier>
-      <HashCode>BggBIBAAAAAAAKAAAAAAAACYIAAACoEARAEgAIwAAgA=</HashCode>
+      <HashCode>BggBIBAAAAAAAKAAAAAAAACYIAAACoAARAEgAIwAAgA=</HashCode>
       <FileName>ViewModel\ServiceShakerControlViewModel.cs</FileName>
     </TypeIdentifier>
   </Class>
@@ -130,28 +130,28 @@
     </TypeIdentifier>
   </Class>
   <Class Name="ShakerService.OilSource.BitAddressConfig">
-    <Position X="39" Y="0.5" Width="1.5" />
+    <Position X="40.75" Y="0.5" Width="1.5" />
     <TypeIdentifier>
       <HashCode>AAAAAAAAAAAAAAAAACAAAAAAAAAAAAACAAAAAAAAABA=</HashCode>
       <FileName>OilSource\BitAddressConfig.cs</FileName>
     </TypeIdentifier>
   </Class>
-  <Class Name="ShakerService.OilSource.OilSource" Collapsed="true">
-    <Position X="44.25" Y="0.5" Width="1.5" />
+  <Class Name="ShakerService.OilSource.OilSource">
+    <Position X="41" Y="2.5" Width="1.5" />
     <TypeIdentifier>
-      <HashCode>AAQAAAAAAAAggABAAAESIIAAAEAAEAIAAABGgAAQAQA=</HashCode>
+      <HashCode>AAQAAAAAAAAgoABAAAESIIAAAEAAEAIAAABGAAAQAQA=</HashCode>
       <FileName>OilSource\OilSource.cs</FileName>
     </TypeIdentifier>
   </Class>
-  <Class Name="ShakerService.OilSource.OilSourceAnalogAddressConfig" Collapsed="true">
-    <Position X="40.75" Y="1.5" Width="1.5" />
+  <Class Name="ShakerService.OilSource.OilSourceAnalogAddressConfig">
+    <Position X="38.25" Y="3.75" Width="1.5" />
     <TypeIdentifier>
       <HashCode>ABAAAAAAAAEAECEAIAAAAAQYAAAAAAAAAAAAAAAgABA=</HashCode>
       <FileName>OilSource\OilSourceAnalogAddressConfig.cs</FileName>
     </TypeIdentifier>
   </Class>
   <Class Name="ShakerService.OilSource.OilSourceConfig">
-    <Position X="42.5" Y="1.5" Width="1.5" />
+    <Position X="32.75" Y="5" Width="1.5" />
     <TypeIdentifier>
       <HashCode>ACAAAAEAAIAAAAAAAAEAAABCKEABAAAAAABACAACgBA=</HashCode>
       <FileName>OilSource\OilSourceConfig.cs</FileName>
@@ -171,21 +171,21 @@
       <FileName>Tools\Log.cs</FileName>
     </TypeIdentifier>
   </Class>
-  <Class Name="ShakerService.Tools.PluginsLoader" Collapsed="true">
-    <Position X="40.75" Y="2.5" Width="1.5" />
+  <Class Name="ShakerService.Tools.PluginsLoader">
+    <Position X="34.75" Y="3.25" Width="1.5" />
     <TypeIdentifier>
       <HashCode>AAABgAAEAAAAAAAAAAAACAAAAAAAAAAAABAMQAIAAAA=</HashCode>
       <FileName>Tools\PluginsLoader.cs</FileName>
     </TypeIdentifier>
   </Class>
-  <Class Name="ShakerService.Tools.ServiceConfigTool" Collapsed="true">
-    <Position X="44.5" Y="1.75" Width="1.5" />
+  <Class Name="ShakerService.Tools.ServiceConfigTool">
+    <Position X="43.5" Y="1.75" Width="1.5" />
     <TypeIdentifier>
       <HashCode>AECAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
       <FileName>Tools\ServiceConfigTool.cs</FileName>
     </TypeIdentifier>
   </Class>
-  <Struct Name="ShakerService.ViewModel.ServiceDataCacheViewModel" Collapsed="true">
+  <Struct Name="ShakerService.ViewModel.ServiceDataCacheViewModel">
     <Position X="40.75" Y="3.75" Width="1.5" />
     <TypeIdentifier>
       <HashCode>AAAAAgAAAAAAAAAABABAAAEAFAIQAAAgQAABgAAAAAA=</HashCode>
@@ -199,14 +199,14 @@
       <FileName>ViewModel\IServiceViewModel.cs</FileName>
     </TypeIdentifier>
   </Interface>
-  <Interface Name="ShakerService.ViewModel.IData" Collapsed="true">
-    <Position X="40.75" Y="5" Width="1.5" />
+  <Interface Name="ShakerService.ViewModel.IData">
+    <Position X="43.5" Y="6.25" Width="1.5" />
     <TypeIdentifier>
       <HashCode>ABAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAACAAAAAA=</HashCode>
       <FileName>ViewModel\ServiceSineDataViewModel.cs</FileName>
     </TypeIdentifier>
   </Interface>
-  <Enum Name="ShakerService.Data.TestType" Collapsed="true">
+  <Enum Name="ShakerService.Data.TestType">
     <Position X="40.75" Y="6" Width="1.5" />
     <TypeIdentifier>
       <HashCode>AAAAAAAAAAAAgAAAAAAAAAAAAAAABAAAAAAAAAAAAAA=</HashCode>

+ 6 - 0
Shaker/OilSource/BitAddressConfig.cs

@@ -5,7 +5,13 @@ namespace ShakerService.OilSource
 {
     public class BitAddressConfig:BaseModel
     {
+        /// <summary>
+        /// 地址
+        /// </summary>
         public string Address = "";
+        /// <summary>
+        /// 位序号
+        /// </summary>
         public byte BitIndex = 0;
         public override object Clone()
         {

+ 32 - 32
Shaker/OilSource/OilSource.cs

@@ -112,7 +112,7 @@ namespace ShakerService.OilSource
             _timer.Enabled = false;
             _timer.AutoReset = true;
             _timer.Stop();
-            Communication.Instance.Context.GetEvent(Topic.CircuitPressure).Subscrip((sender, args) =>
+            Communication.Instance.Context.GetEvent(Topic.CircuitPressure)?.Subscrip((sender, args) =>
             {
                 if(args.Data.Length>=2 && args.Data[0] is int index && args.Data[1] is float pressure)
                 {
@@ -120,38 +120,38 @@ namespace ShakerService.OilSource
                     _PLCConnect?.Write(oilSourceConfig.MainPumpAddress[index].Address, pressure);
                 }
             });
-            Communication.Instance.Context.GetEvent(Topic.CircuitStart).Subscrip((sender, args) =>
+            Communication.Instance.Context.GetEvent(Topic.CircuitStart)?.Subscrip((sender, args) =>
             {
                 if (args.Data.Length >= 2 && args.Data[0] is int index && args.Data[1] is bool state)
                 {
                     if (!oilSourceConfig.MainPumpAddress[index].IsEnabled) return;
                     if (state)
                     {
-                        SetLevel(oilSourceConfig.MainPumpAddress[index].StartAddress, oilSourceConfig.MainPumpAddress[index].StartBitIndex, state);
+                        SetLevel(oilSourceConfig.MainPumpAddress[index].StartAddress, oilSourceConfig.MainPumpAddress[index].StartBitIndex, true);
                     }
                     else
                     {
-                        SetLevel(oilSourceConfig.MainPumpAddress[index].StopAddress, oilSourceConfig.MainPumpAddress[index].StopBitIndex, state);
+                        SetLevel(oilSourceConfig.MainPumpAddress[index].StopAddress, oilSourceConfig.MainPumpAddress[index].StopBitIndex, true);
                     }
                 }
             });
-            Communication.Instance.Context.GetEvent(Topic.CircuitLoad).Subscrip((sender, args) =>
+            Communication.Instance.Context.GetEvent(Topic.CircuitLoad)?.Subscrip((sender, args) =>
             {
                 if (args.Data.Length >= 2 && args.Data[0] is int index && args.Data[1] is bool state)
                 {
                     if (!oilSourceConfig.MainPumpAddress[index].IsLoadEnabled) return;
                     if (state)
                     {
-                        SetLevel(oilSourceConfig.MainPumpAddress[index].LoadAddress, oilSourceConfig.MainPumpAddress[index].LoadBitIndex, state);
+                        SetLevel(oilSourceConfig.MainPumpAddress[index].LoadAddress, oilSourceConfig.MainPumpAddress[index].LoadBitIndex, true);
                     }
                     else
                     {
-                        SetLevel(oilSourceConfig.MainPumpAddress[index].UnLoadAddress, oilSourceConfig.MainPumpAddress[index].UnLoadBitIndex, state);
+                        SetLevel(oilSourceConfig.MainPumpAddress[index].UnLoadAddress, oilSourceConfig.MainPumpAddress[index].UnLoadBitIndex, true);
                     }
                 }
             });
 
-            Communication.Instance.Context.GetEvent(Topic.ForerunnerPressure).Subscrip((sender, args) =>
+            Communication.Instance.Context.GetEvent(Topic.ForerunnerPressure)?.Subscrip((sender, args) =>
             {
                 if (args.Data.Length >= 1 && args.Data[0] is float pressure)
                 {
@@ -159,38 +159,38 @@ namespace ShakerService.OilSource
                     _PLCConnect?.Write(oilSourceConfig.ForerunnerAddress.Address, pressure);
                 }
             });
-            Communication.Instance.Context.GetEvent(Topic.ForerunnerStart).Subscrip((sender, args) =>
+            Communication.Instance.Context.GetEvent(Topic.ForerunnerStart)?.Subscrip((sender, args) =>
             {
                 if (args.Data.Length >= 1  && args.Data[0] is bool state)
                 {
                     if (!oilSourceConfig.ForerunnerAddress.IsEnabled) return;
                     if (state)
                     {
-                        SetLevel(oilSourceConfig.ForerunnerAddress.StartAddress, oilSourceConfig.ForerunnerAddress.StartBitIndex, state);
+                        SetLevel(oilSourceConfig.ForerunnerAddress.StartAddress, oilSourceConfig.ForerunnerAddress.StartBitIndex, true);
                     }
                     else
                     {
-                        SetLevel(oilSourceConfig.ForerunnerAddress.StopAddress, oilSourceConfig.ForerunnerAddress.StopBitIndex, state);
+                        SetLevel(oilSourceConfig.ForerunnerAddress.StopAddress, oilSourceConfig.ForerunnerAddress.StopBitIndex, true);
                     }
                 }
             });
-            Communication.Instance.Context.GetEvent(Topic.ForerunnerLoad).Subscrip((sender, args) =>
+            Communication.Instance.Context.GetEvent(Topic.ForerunnerLoad)?.Subscrip((sender, args) =>
             {
                 if (args.Data.Length >= 1  && args.Data[0] is bool state)
                 {
                     if (!oilSourceConfig.ForerunnerAddress.IsLoadEnabled) return;
                     if (state)
                     {
-                        SetLevel(oilSourceConfig.ForerunnerAddress.LoadAddress, oilSourceConfig.ForerunnerAddress.LoadBitIndex, state);
+                        SetLevel(oilSourceConfig.ForerunnerAddress.LoadAddress, oilSourceConfig.ForerunnerAddress.LoadBitIndex, true);
                     }
                     else
                     {
-                        SetLevel(oilSourceConfig.ForerunnerAddress.UnLoadAddress, oilSourceConfig.ForerunnerAddress.UnLoadBitIndex, state);
+                        SetLevel(oilSourceConfig.ForerunnerAddress.UnLoadAddress, oilSourceConfig.ForerunnerAddress.UnLoadBitIndex, true);
                     }
                 }
             });
 
-            Communication.Instance.Context.GetEvent(Topic.AssistantPressure).Subscrip((sender, args) =>
+            Communication.Instance.Context.GetEvent(Topic.AssistantPressure)?.Subscrip((sender, args) =>
             {
                 if (args.Data.Length >= 1 && args.Data[0] is float pressure)
                 {
@@ -198,38 +198,38 @@ namespace ShakerService.OilSource
                     _PLCConnect?.Write(oilSourceConfig.AssistantAddress.Address, pressure);
                 }
             });
-            Communication.Instance.Context.GetEvent(Topic.AssistantStart).Subscrip((sender, args) =>
+            Communication.Instance.Context.GetEvent(Topic.AssistantStart)?.Subscrip((sender, args) =>
             {
                 if (args.Data.Length >= 1  && args.Data[0] is bool state)
                 {
                     if (!oilSourceConfig.AssistantAddress.IsEnabled) return;
                     if (state)
                     {
-                        SetLevel(oilSourceConfig.AssistantAddress.StartAddress, oilSourceConfig.AssistantAddress.StartBitIndex, state);
+                        SetLevel(oilSourceConfig.AssistantAddress.StartAddress, oilSourceConfig.AssistantAddress.StartBitIndex, true);
                     }
                     else
                     {
-                        SetLevel(oilSourceConfig.AssistantAddress.StopAddress, oilSourceConfig.AssistantAddress.StopBitIndex, state);
+                        SetLevel(oilSourceConfig.AssistantAddress.StopAddress, oilSourceConfig.AssistantAddress.StopBitIndex, true);
                     }
                 }
             });
-            Communication.Instance.Context.GetEvent(Topic.AssistantLoad).Subscrip((sender, args) =>
+            Communication.Instance.Context.GetEvent(Topic.AssistantLoad)?.Subscrip((sender, args) =>
             {
                 if (args.Data.Length >= 1  && args.Data[0] is bool state)
                 {
                     if (!oilSourceConfig.AssistantAddress.IsLoadEnabled) return;
                     if (state)
                     {
-                        SetLevel(oilSourceConfig.AssistantAddress.LoadAddress, oilSourceConfig.AssistantAddress.LoadBitIndex, state);
+                        SetLevel(oilSourceConfig.AssistantAddress.LoadAddress, oilSourceConfig.AssistantAddress.LoadBitIndex, true);
                     }
                     else
                     {
-                        SetLevel(oilSourceConfig.AssistantAddress.UnLoadAddress, oilSourceConfig.AssistantAddress.UnLoadBitIndex, state);
+                        SetLevel(oilSourceConfig.AssistantAddress.UnLoadAddress, oilSourceConfig.AssistantAddress.UnLoadBitIndex, true);
                     }
                 }
             });
 
-            Communication.Instance.Context.GetEvent(Topic.CirculatePressure).Subscrip((sender, args) =>
+            Communication.Instance.Context.GetEvent(Topic.CirculatePressure)?.Subscrip((sender, args) =>
             {
                 if (args.Data.Length >= 1  && args.Data[0] is float pressure)
                 {
@@ -237,48 +237,48 @@ namespace ShakerService.OilSource
                     _PLCConnect?.Write(oilSourceConfig.CirculateAddress.Address, pressure);
                 }
             });
-            Communication.Instance.Context.GetEvent(Topic.CirculateStart).Subscrip((sender, args) =>
+            Communication.Instance.Context.GetEvent(Topic.CirculateStart)?.Subscrip((sender, args) =>
             {
                 if (args.Data.Length >= 1  && args.Data[0] is bool state)
                 {
                     if (!oilSourceConfig.CirculateAddress.IsEnabled) return;
                     if (state)
                     {
-                        SetLevel(oilSourceConfig.CirculateAddress.StartAddress, oilSourceConfig.CirculateAddress.StartBitIndex, state);
+                        SetLevel(oilSourceConfig.CirculateAddress.StartAddress, oilSourceConfig.CirculateAddress.StartBitIndex, true);
                     }
                     else
                     {
-                        SetLevel(oilSourceConfig.CirculateAddress.StopAddress, oilSourceConfig.CirculateAddress.StopBitIndex, state);
+                        SetLevel(oilSourceConfig.CirculateAddress.StopAddress, oilSourceConfig.CirculateAddress.StopBitIndex, true);
                     }
                 }
             });
-            Communication.Instance.Context.GetEvent(Topic.CirculateLoad).Subscrip((sender, args) =>
+            Communication.Instance.Context.GetEvent(Topic.CirculateLoad)?.Subscrip((sender, args) =>
             {
                 if (args.Data.Length >= 1  && args.Data[0] is bool state)
                 {
                     if (!oilSourceConfig.CirculateAddress.IsLoadEnabled) return;
                     if (state)
                     {
-                        SetLevel(oilSourceConfig.CirculateAddress.LoadAddress, oilSourceConfig.CirculateAddress.LoadBitIndex, state);
+                        SetLevel(oilSourceConfig.CirculateAddress.LoadAddress, oilSourceConfig.CirculateAddress.LoadBitIndex, true);
                     }
                     else
                     {
-                        SetLevel(oilSourceConfig.CirculateAddress.UnLoadAddress, oilSourceConfig.CirculateAddress.UnLoadBitIndex, state);
+                        SetLevel(oilSourceConfig.CirculateAddress.UnLoadAddress, oilSourceConfig.CirculateAddress.UnLoadBitIndex, true);
                     }
                 }
             });
 
-            Communication.Instance.Context.GetEvent(Topic.OilEmergencyStop).Subscrip((sender, args) =>
+            Communication.Instance.Context.GetEvent(Topic.OilEmergencyStop)?.Subscrip((sender, args) =>
             {
                 if (args.Data.Length >= 1 && args.Data[0] is bool state)
                 {
                     if (state)
                     {
-                        SetLevel(oilSourceConfig.EmergencyStopAddress.Address, oilSourceConfig.EmergencyStopAddress.BitIndex, state);
+                        SetLevel(oilSourceConfig.EmergencyStopAddress.Address, oilSourceConfig.EmergencyStopAddress.BitIndex, true);
                     }
                     else
                     {
-                        SetLevel(oilSourceConfig.EmergencyStopAddress.Address, oilSourceConfig.EmergencyStopAddress.BitIndex, state);
+                        SetLevel(oilSourceConfig.EmergencyStopAddress.Address, oilSourceConfig.EmergencyStopAddress.BitIndex, true);
                     }
                 }
             });
@@ -379,7 +379,7 @@ namespace ShakerService.OilSource
                     OilSourceStatus.OilSourceAnalogs[i].IsUpperError = _PLCConnect.ReadBit(oilSourceConfig.AnalogAddress[i].UpperErrorAddress, oilSourceConfig.AnalogAddress[i].UpperErrorBitIndex);
                     OilSourceStatus.OilSourceAnalogs[i].IsUpperWarn = _PLCConnect.ReadBit(oilSourceConfig.AnalogAddress[i].UpperWarnAddress, oilSourceConfig.AnalogAddress[i].UpperWarnBitIndex);
                 }
-                Communication.Instance.Context.GetEvent<OilSourceStatusModel>().Publish(this, OilSourceStatus);
+                Communication.Instance.Context.GetEvent<OilSourceStatusModel>()?.Publish(this, OilSourceStatus);
             }
         }
         static OilSource()

+ 33 - 0
Shaker/OilSource/OilSourceAnalogAddressConfig.cs

@@ -2,17 +2,50 @@
 {
     public class OilSourceAnalogAddressConfig
     {
+        /// <summary>
+        /// 名字,与多语言字典文件中的key相同
+        /// </summary>
         public string Name = "";
+        /// <summary>
+        /// 单位
+        /// </summary>
         public string Unit = "";
+        /// <summary>
+        /// 压力设定地址
+        /// </summary>
         public string ValueAddress = "";
 
+        /// <summary>
+        /// 上限警告地址
+        /// </summary>
         public string UpperWarnAddress = "";
+        /// <summary>
+        /// 上限警告bit位
+        /// </summary>
         public byte UpperWarnBitIndex = 0;
+        /// <summary>
+        /// 上限停止地址
+        /// </summary>
         public string UpperErrorAddress = "";
+        /// <summary>
+        /// 上限停止bit位
+        /// </summary>
         public byte UpperErrorBitIndex = 0;
+        /// <summary>
+        /// 低报警地址
+        /// </summary>
         public string LowerWarnAddress = "";
+        /// <summary>
+        /// 低报警bit位
+        /// </summary>
         public byte LowerWarnBitIndex = 0;
+        /// <summary>
+        /// 低停止地址
+        /// </summary>
         public string LowerErrorAddress = "";
+        /// <summary>
+        /// 低停止bit位
+        /// </summary>
         public byte LowerErrorBitIndex = 0;
 
     }

+ 44 - 2
Shaker/OilSource/OilSourceConfig.cs

@@ -5,20 +5,62 @@ namespace ShakerService.OilSource
 {
     public class OilSourceConfig : BaseModel
     {
+        /// <summary>
+        /// 是否启用
+        /// </summary>
         public bool IsEnabled = true;
+        /// <summary>
+        /// 油源IP地址
+        /// </summary>
         public string IP = "127.0.0.1";
-        public int Port = 502; 
+        /// <summary>
+        /// 端口号
+        /// </summary>
+        public int Port = 502;
+        /// <summary>
+        /// 开关控制逻辑
+        /// </summary>
         public LevelLogic LevelLogic = LevelLogic.Edge;
+        /// <summary>
+        /// 电平保持时间
+        /// </summary>
         public int LevelTime = 50;
+        /// <summary>
+        /// 通信协议
+        /// </summary>
         public IPLCConnect.PLCProtocol Protocol = IPLCConnect.PLCProtocol.S7;
+        /// <summary>
+        /// 主油泵地址
+        /// </summary>
         public List<OilSourcePumpAddressConfig> MainPumpAddress = new List<OilSourcePumpAddressConfig>();
+        /// <summary>
+        /// 先导泵地址
+        /// </summary>
         public OilSourcePumpAddressConfig ForerunnerAddress = new OilSourcePumpAddressConfig();
+        /// <summary>
+        /// 循环泵地址
+        /// </summary>
         public OilSourcePumpAddressConfig CirculateAddress = new OilSourcePumpAddressConfig();
+        /// <summary>
+        /// 辅助油路地址
+        /// </summary>
         public OilSourcePumpAddressConfig AssistantAddress = new OilSourcePumpAddressConfig();
-       
+
+        /// <summary>
+        /// 远程/本地地址
+        /// </summary>
         public BitAddressConfig IsRemoteAddress = new BitAddressConfig();
+        /// <summary>
+        /// 急停地址
+        /// </summary>
         public BitAddressConfig EmergencyStopAddress = new BitAddressConfig();
+        /// <summary>
+        /// 模拟量地址
+        /// </summary>
         public List<OilSourceAnalogAddressConfig> AnalogAddress = new List<OilSourceAnalogAddressConfig>();
+        /// <summary>
+        /// 错误信息地址
+        /// </summary>
         public List<BitAddressConfig> ErrorAddress = new List<BitAddressConfig>();
         public static OilSourceConfig ReadConfig()
         {

+ 2 - 4
Shaker/Program.cs

@@ -1,4 +1,5 @@
-using System.Diagnostics;
+using Microsoft.CodeAnalysis;
+using System.Diagnostics;
 using System.Numerics;
 using System.Runtime.CompilerServices;
 using System.Runtime.Intrinsics;
@@ -9,9 +10,6 @@ namespace ShakerService
     {
         static  void Main(string[] args)
         {
-            var real= Enumerable.Range(0, 4000).Select(x => Math.Sin(x / 1000d * Math.PI)).ToArray();
-            var img = new double[real.Length];
-            ShakerService.ViewModel.ServiceDataCacheViewModel.Instance.Calc.FFT.FFT(real,img);
             Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime;
             Service service = new Service();
             service.Init();

+ 2 - 4
Shaker/Service.cs

@@ -1,6 +1,4 @@
-
-using MathNet.Numerics;
-using Shaker.Models;
+using Shaker.Models;
 using Shaker.Models.Tools;
 using ShakerService.Tools;
 using ShakerService.ViewModel;
@@ -114,7 +112,7 @@ namespace ShakerService
         {
             OilSource.OilSource.Default.StatusChanged += (_, args) =>
             {
-                Communication.Instance.Context?.GetEvent(Topic.OilStatusChanged).Publish(this, null, args);
+                Communication.Instance.Context?.GetEvent(Topic.OilStatusChanged)?.Publish(this, null, args);
                 if(args)
                 {
                     OilLock.Set();

+ 1 - 1
Shaker/ShakerFpga.cs

@@ -6,7 +6,7 @@ using System.Diagnostics.CodeAnalysis;
 */
 namespace ShakerService
 {
-    public class ShakerFpga
+    public partial class ShakerFpga
     {
         [AllowNull]
         private static ShakerFpga myFpga;

+ 15 - 15
Shaker/ShakerService.Control.cs

@@ -37,11 +37,11 @@ namespace ShakerService
         [PropertyInit]
         private void SetRandomStartStep()
         {
-            Communication.Instance.Context.GetEvent<RandomTestStep>().Subscrip((sender, args) =>
+            Communication.Instance.Context.GetEvent<RandomTestStep>()?.Subscrip((sender, args) =>
             {
                 ServiceDataCacheViewModel.Instance.RandomStartStep = args.Data;
             });
-            Communication.Instance.Context.GetEvent<MainPageType>().Subscrip((sender, args) =>
+            Communication.Instance.Context.GetEvent<MainPageType>()?.Subscrip((sender, args) =>
             {
                 ServiceShakerControlViewModel.Instance.Model.PageType = args.Data;
             });
@@ -49,7 +49,7 @@ namespace ShakerService
         [PropertyInit]
         private void SyncConfig()
         {
-            Communication.Instance.Context.GetEvent<AllConfig>(Shaker.Models.Topic.SYNCCONFIG).Subscrip((_, _) =>
+            Communication.Instance.Context.GetEvent<AllConfig>(Shaker.Models.Topic.SYNCCONFIG)?.Subscrip((_, _) =>
             {
                 var config = new AllConfig()
                 {
@@ -68,7 +68,7 @@ namespace ShakerService
         [PropertyInit]
         private void InitStartControl()
         {
-            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.START).Subscrip((_, _) =>
+            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.START)?.Subscrip((_, _) =>
             {
                 StartTrigger();
                 Log.Default.Info("开始");
@@ -77,7 +77,7 @@ namespace ShakerService
         [PropertyInit]
         private void InitStartRandomTest()
         {
-            Communication.Instance.Context.GetEvent(Topic.STARTRANDOMTEST).Subscrip((_, _) =>
+            Communication.Instance.Context.GetEvent(Topic.STARTRANDOMTEST)?.Subscrip((_, _) =>
             {
 
             });
@@ -85,7 +85,7 @@ namespace ShakerService
         [PropertyInit]
         private void InitRiseTableControl()
         {
-            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.RISETABLE).Subscrip((_, _) =>
+            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.RISETABLE)?.Subscrip((_, _) =>
             {
                 RiseTable();
                 Log.Default.Info("升台面");
@@ -94,7 +94,7 @@ namespace ShakerService
         [PropertyInit]
         private void InitZeroChangeControl()
         {
-            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.ZEROCHANGE).Subscrip((_, e) =>
+            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.ZEROCHANGE)?.Subscrip((_, e) =>
             {
                 ZeroChange((float)e.Data[0]);
                 Log.Default.Info("修改工作位:" + e.Data[0]);
@@ -103,7 +103,7 @@ namespace ShakerService
         [PropertyInit]
         private void InitDropTableControl()
         {
-            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.DROPTABLE).Subscrip((_, _) =>
+            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.DROPTABLE)?.Subscrip((_, _) =>
             {
                 DropTable();
                 Log.Default.Info("降台面");
@@ -112,7 +112,7 @@ namespace ShakerService
         [PropertyInit]
         private void InitStopSignalGenControl()
         {
-            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.STOPSIGNALGEN).Subscrip((_, _) =>
+            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.STOPSIGNALGEN)?.Subscrip((_, _) =>
             {
                 StopSignalGen();
                 Log.Default.Info("停止信号发生");
@@ -121,7 +121,7 @@ namespace ShakerService
         [PropertyInit]
         private void InitValvePowerControl()
         {
-            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.VALVEPOWER).Subscrip((_, e) =>
+            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.VALVEPOWER)?.Subscrip((_, e) =>
             {
                 ValvePower((bool)e.Data[0]);
                 Log.Default.Info($"阀{((bool)e.Data[0]?"上电":"去电")}");
@@ -134,7 +134,7 @@ namespace ShakerService
             {
                 Stop();
             });
-            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.STOP).Subscrip((_, _) =>
+            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.STOP)?.Subscrip((_, _) =>
             {
                 Stop();
             });
@@ -142,7 +142,7 @@ namespace ShakerService
         [PropertyInit]
         private void InitStartGen()
         {
-            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.STARTSIGNALGEN).Subscrip((_, _) =>
+            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.STARTSIGNALGEN)?.Subscrip((_, _) =>
             {
                 StartGen();
                 Log.Default.Info("开始信号发生");
@@ -151,7 +151,7 @@ namespace ShakerService
         [PropertyInit]
         private void InitResetErrorControl()
         {
-            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.RESETERROR).Subscrip((_, _) =>
+            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.RESETERROR)?.Subscrip((_, _) =>
             {
                 ResetError();
                 Log.Default.Info("复位");
@@ -160,7 +160,7 @@ namespace ShakerService
         [PropertyInit]
         private void InitExitControl()
         {
-            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.EXIT).Subscrip((_, _) =>
+            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.EXIT)?.Subscrip((_, _) =>
             {
                 StopService();
             });
@@ -168,7 +168,7 @@ namespace ShakerService
         private void SendData(float[,] data)
         {
             Log.Default.Debug("发送数据");
-            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.DATA).Publish(this, null, data);
+            Communication.Instance.Context.GetEvent(Shaker.Models.Topic.DATA)?.Publish(this, null, data);
             
         }
     }

+ 2 - 0
Shaker/ShakerService.csproj

@@ -6,10 +6,12 @@
     <TargetFramework>net8.0</TargetFramework>
     <ImplicitUsings>enable</ImplicitUsings>
     <Nullable>enable</Nullable>
+    <EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
   </PropertyGroup>
 
   <ItemGroup>
     <PackageReference Include="log4net" Version="3.0.3" />
+    <PackageReference Include="MathNet.Numerics" Version="5.0.0" />
   </ItemGroup>
 
   <ItemGroup>

+ 7 - 1
Shaker/ViewModel/ServiceDataCacheViewModel.cs

@@ -24,10 +24,16 @@ namespace ShakerService.ViewModel
             return DataCache.GetLength(index);
         }
         public float[] ReadedDataCache = new float[0];
+        /// <summary>
+        /// 时域原始数据缓存
+        /// </summary>
         public float[,] DataCache = new float[0, 0];
         public float[] SensitivityValues = new float[0];
         public bool IsSignalStart = false;
-        public Data.TestType CurrentTestType  = Data.TestType.Sine;
+        /// <summary>
+        /// 当前试验类型
+        /// </summary>
+        public Data.TestType CurrentTestType = Data.TestType.Sine;
         public bool IsStart = false;
         public RandomTestStep RandomStartStep = RandomTestStep.Start;
         public ref float GetDataCachePin(int row,int col)

+ 13 - 4
Shaker/ViewModel/ServiceRandomConfigViewModel.cs

@@ -1,5 +1,4 @@
-using MathNet.Numerics;
-using Shaker.Models;
+using Shaker.Models;
 using ShakerService.Tools;
 using System;
 using System.Collections.Generic;
@@ -54,7 +53,7 @@ namespace ShakerService.ViewModel
             model.SpectralTables = Communication.Instance.DbConnection.Query<RandomSpectralTableModel>($"select * from {nameof(SpectralTables)}")?.ToList() ?? new List<RandomSpectralTableModel>();
             UpModel(model);
             SaveData();
-            Communication.Instance.Context.GetEvent<RandomConfigModel>().Subscrip((sender, args) =>
+            Communication.Instance.Context.GetEvent<RandomConfigModel>()?.Subscrip((sender, args) =>
             {
                 Log.Default.Debug(nameof(RandomConfigModel));
                 UpModel(args.Data);
@@ -128,7 +127,17 @@ namespace ShakerService.ViewModel
                 StartWindow[i] = Math.Pow(Math.Sin(d),3);
                 StopWindow[i] = Math.Pow(Math.Cos(d), 3);
             }
-            HanningWindow = Window.Hann((int)FFTHalfFrameLength);
+            HanningWindow = CalcHanningWindow(FFTHalfFrameLength);
+        }
+        private double[] CalcHanningWindow(uint count)
+        {
+            if(count  ==0) throw new ArgumentOutOfRangeException(nameof(count));
+            double[] window = new double[count];
+            for(int i=0;i<count;i++)
+            {
+                window[i] = (1 - Math.Cos(Math.PI * 2 * i / count)) * 0.5;
+            }
+            return window;
         }
         
         public ServiceRandomDataViewModel RandomData { get; } = new ServiceRandomDataViewModel();

+ 3 - 1
Shaker/ViewModel/ServiceShakerConfigViewModel.cs

@@ -12,6 +12,7 @@ namespace ShakerService.ViewModel
 {
     internal class ServiceShakerConfigViewModel:BaseServiceViewModel<Shaker.Models.ShakerConfigModel>
     {
+        public float DisplacementBias => Model.DisplacementBias;
         public string BitstreamMD5 { get => Model.BitstreamMD5; set => Model.BitstreamMD5 = value; }
         public string BitfileVersion { get => Model.BitfileVersion; set => Model.BitfileVersion = value; }
         public string SignatureRegister { get => Model.SignatureRegister; set => Model.SignatureRegister = value; }
@@ -80,7 +81,7 @@ namespace ShakerService.ViewModel
             }
             UpModel(model);
             SaveData();
-            Communication.Instance.Context.GetEvent<Shaker.Models.ShakerConfigModel>().Subscrip((sender, args) =>
+            Communication.Instance.Context.GetEvent<Shaker.Models.ShakerConfigModel>()?.Subscrip((sender, args) =>
             {
                 Log.Default.Info($"修改{nameof(ShakerConfigModel)}");
                 UpModel(args.Data);
@@ -95,6 +96,7 @@ namespace ShakerService.ViewModel
             try
             {
                 base.SetFpga();
+                ShakerFpga.Instance.DisplacementBias.Value = DisplacementBias;
                 ShakerFpga.Instance.MaxRiseCount.Value = MaxRiseCount;
                 ShakerFpga.Instance.MaxZeroChangedCount.Value = MaxZeroChangedCount;
                 ShakerFpga.Instance.MaxSignalCount.Value = MaxSignalCount;

+ 1 - 2
Shaker/ViewModel/ServiceShakerControlViewModel.cs

@@ -27,7 +27,7 @@ namespace ShakerService.ViewModel
         public List<SerivceValveConfigItemViewModel> ValveConfig { get; } = new List<SerivceValveConfigItemViewModel>();
         public List<ServiceSweepControlItemViewModel> SweepControlItems { get; } = new List<ServiceSweepControlItemViewModel>();
         public float MaxDisplacementIntegral => Model.MaxDisplacementIntegral;
-        public float DisplacementBias => Model.DisplacementBias;
+
         public bool OilStopped => Model.OilStopped;
         public bool DisplacementOpenLoop => Model.DisplacementOpenLoop;
         public bool OutSignal {get=> Model.OutSignal;set=>Model.OutSignal = value; }
@@ -73,7 +73,6 @@ namespace ShakerService.ViewModel
                 ShakerFpga.Instance.OilStopped.Value = OilStopped;
                 ShakerFpga.Instance.DisplacementOpenLoop.Value = DisplacementOpenLoop;
                 ShakerFpga.Instance.OutSignal.Value = OutSignal;
-                ShakerFpga.Instance.DisplacementBias.Value = DisplacementBias;
                 ShakerFpga.Instance.DisplacementI.Value = DisplacementI / ServiceShakerConfigViewModel.Instance.SampleRate;
                 ShakerFpga.Instance.DisplacementP.Value = DisplacementP;
                 ShakerFpga.Instance.MaxDisplacementIntegral.Value = MaxDisplacementIntegral;

+ 3 - 0
Shaker/ViewModel/ServiceSineDataViewModel.cs

@@ -63,6 +63,9 @@ namespace ShakerService.ViewModel
         }
     }
 
+    /// <summary>
+    /// 当前试验类型
+    /// </summary>
     internal interface IData
     {
         public void ClearCache();

+ 5 - 8
ShakerControl.sln

@@ -113,10 +113,13 @@ Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Timer", "Timer\Timer\Timer.
 EndProject
 Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "FFTW", "Calc\FFTW\FFTW.shproj", "{3563CD92-0BB6-4DD0-BFB9-285524BC8DFB}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModBus", "PLCConnect\ModBus\ModBus.csproj", "{ED35D74A-E634-4CE3-A57A-DA1B3E1840A7}"
-EndProject
 Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "ShakerFile", "ShakerFile\ShakerFile\ShakerFile.shproj", "{1B007F83-8D00-4C26-AD5B-27634A5CCCFC}"
 EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F7A271C7-AF45-4F7A-8072-3B8615432A2B}"
+	ProjectSection(SolutionItems) = preProject
+		.editorconfig = .editorconfig
+	EndProjectSection
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -251,10 +254,6 @@ Global
 		{2A1F115F-2655-4258-81C0-DF3946617594}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{2A1F115F-2655-4258-81C0-DF3946617594}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{2A1F115F-2655-4258-81C0-DF3946617594}.Release|Any CPU.Build.0 = Release|Any CPU
-		{ED35D74A-E634-4CE3-A57A-DA1B3E1840A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{ED35D74A-E634-4CE3-A57A-DA1B3E1840A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{ED35D74A-E634-4CE3-A57A-DA1B3E1840A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{ED35D74A-E634-4CE3-A57A-DA1B3E1840A7}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -298,7 +297,6 @@ Global
 		{A47488D9-77AC-49F1-A1A7-572E25B9938B} = {E6D664F7-E527-4F99-B705-D8A9B0AAF98B}
 		{28886AC2-7F43-4E10-9AC0-0BF30859772B} = {E6D664F7-E527-4F99-B705-D8A9B0AAF98B}
 		{3563CD92-0BB6-4DD0-BFB9-285524BC8DFB} = {77E3D4F2-F63C-4E2F-899E-CA5268B6FB53}
-		{ED35D74A-E634-4CE3-A57A-DA1B3E1840A7} = {8056D376-ADBF-4C14-B257-F5179F37E98C}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {C35FB2A6-578C-4027-8E68-84ADFBD6A70F}
@@ -332,7 +330,6 @@ Global
 		Calc\FFTW\FFTW.projitems*{e82e51e4-0ca1-4b1f-a2a7-b3b9eb22b96b}*SharedItemsImports = 5
 		Calc\FxpConvert.Common\Calc.Common.projitems*{e82e51e4-0ca1-4b1f-a2a7-b3b9eb22b96b}*SharedItemsImports = 5
 		NativeLoader\NativeLoader.projitems*{e82e51e4-0ca1-4b1f-a2a7-b3b9eb22b96b}*SharedItemsImports = 5
-		PLCConnect\NModbus\NModbus.projitems*{ed35d74a-e634-4ce3-a57a-da1b3e1840a7}*SharedItemsImports = 5
 		OxyPlot\OxyPlot\OxyPlot.projitems*{f1f157cd-990c-48a9-8ec2-c0d5dee8d8a4}*SharedItemsImports = 5
 	EndGlobalSection
 EndGlobal