Переглянути джерело

修复了读取定点数组时的错误

l2736 3 місяців тому
батько
коміт
937d48d4d4
76 змінених файлів з 1672 додано та 789 видалено
  1. 43 0
      Avalonia/ShakerApp/App.axaml.cs
  2. 1 0
      Avalonia/ShakerApp/Models/StatisticsModel.cs
  3. 16 0
      Avalonia/ShakerApp/Models/Topic.cs
  4. 1 1
      Avalonia/ShakerApp/Tools/EnumHelper.cs
  5. 16 0
      Avalonia/ShakerApp/ViewModels/IDataPreview.cs
  6. 1 0
      Avalonia/ShakerApp/ViewModels/MainPage/MainPageViewModel.cs
  7. 14 5
      Avalonia/ShakerApp/ViewModels/MainPage/SineMainPageViewModel.cs
  8. 3 3
      Avalonia/ShakerApp/ViewModels/MainViewModel.cs
  9. 48 48
      Avalonia/ShakerApp/ViewModels/ShakerConfig/RandomConfigViewModel.cs
  10. 6 6
      Avalonia/ShakerApp/ViewModels/ShakerConfig/RandomSpectrumItemViewModel.cs
  11. 13 13
      Avalonia/ShakerApp/ViewModels/ShakerConfig/ShakerConfigViewModel.cs
  12. 37 37
      Avalonia/ShakerApp/ViewModels/ShakerConfig/SweepConfigViewModel.cs
  13. 7 7
      Avalonia/ShakerApp/ViewModels/ShakerConfig/SweepData.cs
  14. 6 6
      Avalonia/ShakerApp/ViewModels/ShakerConfig/SweepItemViewModel.cs
  15. 14 3
      Avalonia/ShakerApp/ViewModels/ShakerControl/ShakerControlViewModel.cs
  16. 2 2
      Avalonia/ShakerApp/ViewModels/ShakerControl/ValveConfigItemViewModel.cs
  17. 3 1
      Avalonia/ShakerApp/ViewModels/ShakerDataViewModel.cs
  18. 11 166
      Avalonia/ShakerApp/ViewModels/ShakerStatus/ShakerStatusViewModel.cs
  19. 182 0
      Avalonia/ShakerApp/ViewModels/SignalPreview/AnalogSignalPreviewViewModel.cs
  20. 27 3
      Avalonia/ShakerApp/ViewModels/SignalPreview/SignalPreviewViewModel.cs
  21. 3 0
      Avalonia/ShakerApp/ViewModels/StatisticsViewModel.cs
  22. 20 6
      Avalonia/ShakerApp/Views/DebugView/DebugView.axaml
  23. 8 0
      Avalonia/ShakerApp/Views/MainPage/SineMainPage.axaml
  24. 4 145
      Avalonia/ShakerApp/Views/ShakerStatusControl/ShakerStatusControlView.axaml
  25. 103 0
      Avalonia/ShakerApp/Views/SignalPreview/AnalogSignalPreviewView.axaml
  26. 13 0
      Avalonia/ShakerApp/Views/SignalPreview/AnalogSignalPreviewView.axaml.cs
  27. 11 7
      Avalonia/ShakerApp/Views/SignalPreview/SignalPreviewView.axaml
  28. 23 1
      Calc/FxpConvert.Common/ICalc.cs
  29. 437 0
      Calc/SIMDFxpConvert/SIMDCalc.cs
  30. 2 2
      Calc/SIMDFxpConvert/SIMDFxpConverter.cs
  31. 2 2
      Communication/NetMQ/Core/Mailbox.cs
  32. 1 1
      Communication/TcpEventBus/ISocket.cs
  33. 32 0
      Communication/TcpEventBus/Server.cs
  34. 0 8
      Communication/TcpEventBus/TcpEventBus.cs
  35. 1 0
      Language/Zh-CN/Language.axaml
  36. 146 26
      NIFPGA/FPGA.cs
  37. 20 8
      NIFPGA/FPGAArrayFXPReadProperty.cs
  38. 35 13
      NIFPGA/FPGAArrayFXPWriteProperty.cs
  39. 1 0
      NIFPGA/FPGABaseProperty.cs
  40. 4 4
      NIFPGA/FPGAFXPReadProperty.cs
  41. 6 6
      NIFPGA/FPGAFXPWriteProperty.cs
  42. 8 4
      NIFPGA/Fifo.cs
  43. 1 1
      NIFPGA/NiFpga_FifoFlowControl.cs
  44. 1 1
      NIFPGA/NiFpga_HostBufferType.cs
  45. 2 2
      OxyPlot/OxyPlot.Avalonia/Tracker/TrackerControl.cs
  46. 7 0
      Shaker.Model/AnalogType.cs
  47. 4 4
      Shaker.Model/Models/RandomConfigModel.cs
  48. 6 6
      Shaker.Model/Models/RandomSpectrumItemModel.cs
  49. 12 12
      Shaker.Model/Models/ShakerConfigModel.cs
  50. 4 4
      Shaker.Model/Models/SineDataModel.cs
  51. 14 14
      Shaker.Model/Models/SweepConfigModel.cs
  52. 6 6
      Shaker.Model/Models/SweepItemModel.cs
  53. 2 2
      Shaker.Model/Models/ValveConfigItemModel.cs
  54. 34 34
      Shaker.Model/Tools/Tools.cs
  55. 2 0
      Shaker/OilSource/OilSource.cs
  56. 9 6
      Shaker/Service.RTInit.cs
  57. 18 5
      Shaker/Service.cs
  58. 1 0
      Shaker/ServiceConfig.cs
  59. 2 0
      Shaker/ShakerFpga.cs
  60. 8 8
      Shaker/ShakerService.CalcDisplacement.cs
  61. 15 3
      Shaker/ShakerService.Control.cs
  62. 42 58
      Shaker/ShakerService.ReadConfig.cs
  63. 6 10
      Shaker/ShakerService.ReadFifo.cs
  64. 1 1
      Shaker/ShakerService.WriteConfig.cs
  65. 13 3
      Shaker/Tools/Log.cs
  66. 2 2
      Shaker/ViewModel/SerivceValveConfigItemViewModel.cs
  67. 27 0
      Shaker/ViewModel/ServiceDataCacheViewModel.cs
  68. 6 4
      Shaker/ViewModel/ServiceRandomConfigViewModel.cs
  69. 6 6
      Shaker/ViewModel/ServiceRandomSpectrumItemViewModel.cs
  70. 34 13
      Shaker/ViewModel/ServiceShakerConfigViewModel.cs
  71. 11 5
      Shaker/ViewModel/ServiceShakerControlViewModel.cs
  72. 1 2
      Shaker/ViewModel/ServiceShakerStatusViewModel.cs
  73. 10 6
      Shaker/ViewModel/ServiceSineDataViewModel.cs
  74. 28 23
      Shaker/ViewModel/ServiceSweepConfigViewModel.cs
  75. 6 6
      Shaker/ViewModel/ServiceSweepItemViewModel.cs
  76. 0 8
      ShakerControl.sln

+ 43 - 0
Avalonia/ShakerApp/App.axaml.cs

@@ -2,6 +2,8 @@
 using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Data.Core.Plugins;
 using Avalonia.Markup.Xaml;
+using FxpConvert.Common;
+
 #if DEBUG
 using HotAvalonia;
 #endif
@@ -18,6 +20,7 @@ public partial class App : Application
 {
     public unsafe override void Initialize()
     {
+        Test();
 #if DEBUG
         if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
         {
@@ -26,7 +29,47 @@ public partial class App : Application
 #endif
         AvaloniaXamlLoader.Load(this);
     }
+    private void Test()
+    {
+        IFxpConvert convert = new SIMDFxpConvert.SIMDFxpConverter();
+        uint count = 4;
+        double[] f = new double[] { -1, -2, 1, 2 };
+        ulong[] f2 = new ulong[count];
+        NiFpga_FxpTypeInfo typeInfo = new NiFpga_FxpTypeInfo()
+        {
+            integerWordLength = 5,
+            Delta = 0.000031,
+            isSigned = true,
+            Max = 15.999969,
+            Min = -16,
+            wordLength = 20
+        };
+        convert.DoubleConvertToDxp(ref f[0], typeInfo, ref f2[0], count);
+        byte[] bytes = new byte[(int)Math.Ceiling(typeInfo.wordLength * count / 8.0)];
+        string s = string.Empty;
+        
+        for(int i=0;i<f2.Length;i++)
+        {
+            s += f2[i].ToString("b").PadLeft(64,'0').Substring(64 - typeInfo.wordLength, typeInfo.wordLength);
+        }
+        for(int i = 0; i < bytes.Length;i++)
+        {
+            bytes[i] = System.Convert.ToByte(s.Substring(i * 8, Math.Min(8, s.Length - i * 8)), 2);
+        }
 
+        s = string.Empty;
+        for(int i=0;i<bytes.Length;i++)
+        {
+            s += bytes[i].ToString("b").PadLeft(8, '0');
+        }
+        ulong[] f3 = new ulong[count];
+        for(int i=0;i<f3.Length;i++)
+        {
+            f3[i] = System.Convert.ToUInt64(s.Substring(i * typeInfo.wordLength, typeInfo.wordLength),2);
+        }
+        double[] f4 = new double[count];
+        convert.FxpConvertToDouble(ref f3[0], typeInfo, ref f4[0], count);
+    }
     public override void OnFrameworkInitializationCompleted()
     {
         BindingPlugins.DataValidators.RemoveAt(0);

+ 1 - 0
Avalonia/ShakerApp/Models/StatisticsModel.cs

@@ -15,6 +15,7 @@ namespace ShakerApp.Models
         public float Max;
         public float Min;
         public float RMS;
+        public float Average;
         public string Unit = string.Empty;
         public object Clone()
         {

+ 16 - 0
Avalonia/ShakerApp/Models/Topic.cs

@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ShakerApp.Models
+{
+    public class Topic
+    {
+        /// <summary>
+        /// 系统参数发生改变,用以通知所有程序需要重新初始化曲线信息
+        /// </summary>
+        public static string InitSeries => "InitSeries";
+    }
+}

+ 1 - 1
Avalonia/ShakerApp/Tools/EnumHelper.cs

@@ -6,7 +6,7 @@ namespace ShakerApp.Tools
 {
     public static class EnumHelper
     {
-        public static string Description(this Enum e)
+        public static string Description<T>(this T e) where T:Enum
         {
             if (e == null || !e.GetType().IsEnum) return "";
             return (e.GetType()?

+ 16 - 0
Avalonia/ShakerApp/ViewModels/IDataPreview.cs

@@ -0,0 +1,16 @@
+using CommunityToolkit.Mvvm.Input;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Input;
+
+namespace ShakerApp.ViewModels
+{
+    public interface IDataPreview
+    {
+        public bool UpSignalData { get; set; }
+        public ICommand WindowCloseCommand => new RelayCommand(() => UpSignalData = false);
+    }
+}

+ 1 - 0
Avalonia/ShakerApp/ViewModels/MainPage/MainPageViewModel.cs

@@ -54,6 +54,7 @@ namespace ShakerApp.ViewModels
             set
             {
                 SetProperty(ref mainPageType, value);
+                ShakerControlViewModel.Instance.PageType = value;
                 Content = MainPages.First(x => x.PageType == value).Content;
                 MainPage = MainPageViewModels.First(x => x.PageType == value);
             }

+ 14 - 5
Avalonia/ShakerApp/ViewModels/MainPage/SineMainPageViewModel.cs

@@ -86,6 +86,13 @@ namespace ShakerApp.ViewModels
                 }
                 PlotModel.InvalidatePlot(true);
             });
+            GetEvent<AllConfig>().Subscrip((_, _) =>
+            {
+                CommunicationViewModel.Intance.LocalCommunication?.GetEvent<SineDataModel>().Subscrip((_, args) =>
+                {
+                    UpdateData(args.Data);
+                });
+            });
         }
         static SineMainPageViewModel()
         {
@@ -146,7 +153,7 @@ namespace ShakerApp.ViewModels
                     }
                 }
                 if (index == -1) index = datas.Count - 1;
-                float value = 0; float upstop = 0; float upwarn = 0; float downstop = 0; float downwarn = 0;
+                double value = 0; double upstop = 0; double upwarn = 0; double downstop = 0; double downwarn = 0;
                 SweepConfigViewModel.Instance.Model.CalcAmpt(sine.CurrentFrequency, ref value, ref upstop, ref upwarn, ref downstop, ref downwarn);
                 datas.Insert(index + 1, new SweepData()
                 {
@@ -180,15 +187,17 @@ namespace ShakerApp.ViewModels
         }
 
         [PropertyAssociation(nameof(SineDataModel.TotalTime))]
-        public float TotalTime { get => Model.TotalTime; set => SetProperty(ref Model.TotalTime, value); }
+        public double TotalTime { get => Model.TotalTime; set => SetProperty(ref Model.TotalTime, value); }
         [PropertyAssociation(nameof(SineDataModel.RunTime))]
-        public float RunTime { get => Model.RunTime; set => SetProperty(ref Model.RunTime, value); }
+        public double RunTime { get => Model.RunTime; set => SetProperty(ref Model.RunTime, value); }
         [PropertyAssociation(nameof(SineDataModel.CurrentFrequency))]
-        public float CurrentFrequency { get => Model.CurrentFrequency; set => SetProperty(ref Model.CurrentFrequency, value); }
+        public double CurrentFrequency { get => Model.CurrentFrequency; set => SetProperty(ref Model.CurrentFrequency, value); }
         [PropertyAssociation(nameof(SineDataModel.CurrentAcceleration))]
-        public float CurrentAcceleration { get => Model.CurrentAcceleration; set => SetProperty(ref Model.CurrentAcceleration, value); }
+        public double CurrentAcceleration { get => Model.CurrentAcceleration; set => SetProperty(ref Model.CurrentAcceleration, value); }
         [PropertyAssociation(nameof(SineDataModel.SweepDirection))]
         public SweepDirection SweepDirection { get => Model.SweepDirection; set => SetProperty(ref Model.SweepDirection, value); }
+        [PropertyAssociation(nameof(SineDataModel.SweepStep))]
+        public SweepStep SweepStep { get => Model.SweepStep; set => SetProperty(ref Model.SweepStep, value); }
         [PropertyAssociation(nameof(SineDataModel.SweepIndex))]
         public uint SweepIndex { get => Model.SweepIndex; set => SetProperty(ref Model.SweepIndex, value); }
         [PropertyAssociation(nameof(SineDataModel.MainPageType))]

+ 3 - 3
Avalonia/ShakerApp/ViewModels/MainViewModel.cs

@@ -64,7 +64,7 @@ public class MainViewModel : ViewModelBase<IModel>
     {
         Dialogs.Ask(App.Current?.FindResource("PromptExitMsg")+"",()=>
         {
-            CommunicationViewModel.Intance.LocalCommunication?.GetEvent(Topic.EXIT)?.Publish(this, null);
+            CommunicationViewModel.Intance.LocalCommunication?.GetEvent(Topic.STOP)?.Publish(this, null);
             Environment.Exit(0);
         });
     }
@@ -198,7 +198,7 @@ public class MainViewModel : ViewModelBase<IModel>
     public ICommand CloseCommand => new RelayCommand(Close);
     private void Close()
     {
-        CommunicationViewModel.Intance.LocalCommunication?.GetEvent(Topic.EXIT)?.Publish(this, null);
+        CommunicationViewModel.Intance.LocalCommunication?.GetEvent(Topic.STOP)?.Publish(this, null);
         Environment.Exit(0);
     }
     public ICommand DebugCommand => new RelayCommand<string?>(Debug);
@@ -281,7 +281,7 @@ public class MainViewModel : ViewModelBase<IModel>
     {
         Dialogs.Ask(App.Current?.FindResource("AskDisconnect") + "", () =>
         {
-            CommunicationViewModel.Intance.LocalCommunication?.GetEvent(Topic.EXIT).Publish(this, null);
+            CommunicationViewModel.Intance.LocalCommunication?.GetEvent(Topic.STOP).Publish(this, null);
             CommunicationViewModel.Intance.DisConnect();
         });
     }

+ 48 - 48
Avalonia/ShakerApp/ViewModels/ShakerConfig/RandomConfigViewModel.cs

@@ -175,7 +175,7 @@ namespace ShakerApp.ViewModels
         [PropertyAssociation(nameof(RandomConfigModel.SpectrumItemsCount))]
         public uint SpectrumItemsCount => Model.SpectrumItemsCount;
         [PropertyAssociation(nameof(RandomConfigModel.HanningWindowCompensationCoefficient))]
-        public float HanningWindowCompensationCoefficient { get => Model.HanningWindowCompensationCoefficient; set => SetProperty(ref Model.HanningWindowCompensationCoefficient, value); }
+        public double HanningWindowCompensationCoefficient { get => Model.HanningWindowCompensationCoefficient; set => SetProperty(ref Model.HanningWindowCompensationCoefficient, value); }
         [PropertyAssociation(nameof(RandomConfigModel.LinearAverage))]
         public uint LinearAverage { get => Model.LinearAverage; set => SetProperty(ref Model.LinearAverage, value); }
         [PropertyAssociation(nameof(RandomConfigModel.ExponentialAverage))]
@@ -183,7 +183,7 @@ namespace ShakerApp.ViewModels
         [PropertyAssociation(nameof(RandomConfigModel.LinearAverage),nameof(RandomConfigModel.ExponentialAverage))]
         public uint DOF => (LinearAverage << 1) * ((ExponentialAverage << 1) - 1);
         [PropertyAssociation(nameof(RandomConfigModel.MaxFrequency),nameof(SpectrumLines))]
-        public float FrequencyResolution => (float)MaxFrequency / (float)SpectrumLines;
+        public double FrequencyResolution => (double)MaxFrequency / (double)SpectrumLines;
         [PropertyAssociation(nameof(RandomConfigModel.RandomSampleRate))]
         public uint RandomSampleRate => Model.RandomSampleRate;
         List<OxyPlot.Series.LineSeries> lineSeries = new List<OxyPlot.Series.LineSeries>();
@@ -196,11 +196,11 @@ namespace ShakerApp.ViewModels
         List<LineStyle> lineStyles = new List<LineStyle>() { LineStyle.Solid, LineStyle.Solid, LineStyle.Solid, LineStyle.LongDashDotDot, LineStyle.LongDashDotDot };
         List<string> properties = new List<string>() { nameof(SweepData.TargetAcceleration), nameof(SweepData.UpStopAcceleration), nameof(SweepData.DownStopAcceleration), nameof(SweepData.UpWarnAcceleration), nameof(SweepData.DownWarnAcceleration) };
         List<SweepData> datas = new List<SweepData>();
-        private float rmsAcceleration = 0;
+        private double rmsAcceleration = 0;
         private double maxDisplacement;
         private double maxVelocity;
         private bool canResetRMS = false;
-        private float resetRMS;
+        private double resetRMS;
 
         [PropertyAssociation(nameof(RandomConfigModel.MaxFrequency))]
         public RandomMaxFrequency MaxFrequency
@@ -213,11 +213,11 @@ namespace ShakerApp.ViewModels
             }
         }
         public bool CanResetRMS { get => canResetRMS; set =>SetProperty(ref canResetRMS, value); }
-        public float ResetRMS { get => resetRMS; set =>SetProperty(ref resetRMS , value); }
+        public double ResetRMS { get => resetRMS; set =>SetProperty(ref resetRMS , value); }
         [PropertyAssociation(nameof(RandomConfigModel.SynthesisType))]
         public AccelerationSynthesisType SynthesisType { get => Model.SynthesisType; set => SetProperty(ref Model.SynthesisType, value); }
         [PropertyAssociation(nameof(RandomConfigModel.MinFrequency))]
-        public float MinFrequency { get => Model.MinFrequency; set => SetProperty(ref Model.MinFrequency, value); }
+        public double MinFrequency { get => Model.MinFrequency; set => SetProperty(ref Model.MinFrequency, value); }
         [PropertyAssociation(nameof(RandomConfigModel.SpectrumLines))]
         public SpectrumLines SpectrumLines
         {
@@ -229,7 +229,7 @@ namespace ShakerApp.ViewModels
             }
         }
         [PropertyAssociation(nameof(RandomConfigModel.Sigma))]
-        public float Sigma { get => Model.Sigma; set => SetProperty(ref Model.Sigma, value); }
+        public double Sigma { get => Model.Sigma; set => SetProperty(ref Model.Sigma, value); }
 
         [PropertyAssociation(nameof(RandomConfigModel.RandomSampleRate),nameof(RandomConfigModel.MaxFrequency),nameof(RandomConfigModel.SpectrumLines))]
         public uint FFTLength => (uint)(Model.RandomSampleRate / (float)MaxFrequency * (uint)SpectrumLines);
@@ -243,25 +243,25 @@ namespace ShakerApp.ViewModels
         [PropertyAssociation(nameof(RandomConfigModel.WarnLines))]
         public uint WarnLines { get => Model.WarnLines; set => SetProperty(ref Model.WarnLines, value); }
         [PropertyAssociation(nameof(RandomConfigModel.StopRMS))]
-        public float StopRMS { get => Model.StopRMS; set => SetProperty(ref Model.StopRMS, value); }
+        public double StopRMS { get => Model.StopRMS; set => SetProperty(ref Model.StopRMS, value); }
         public OxyPlot.PlotModel AccelerationModel { get; } = new OxyPlot.PlotModel();
 
         public PlotModel DisplacementModel { get; } = new PlotModel();
         public PlotModel VelocityModel { get; } = new PlotModel();
         public static RandomConfigViewModel Instance { get; } = new RandomConfigViewModel();
         [PropertyAssociation(nameof(RandomConfigModel.Sigma))]
-        public float MaxAcceleration => RMSAcceleration * Sigma;
+        public double MaxAcceleration => RMSAcceleration * Sigma;
         public double MaxDisplacement { get => maxDisplacement; set =>SetProperty(ref maxDisplacement , value); }
         public double MaxVelocity { get => maxVelocity; set =>SetProperty(ref maxVelocity , value); }
         public bool AccelerationOverLimit => MaxAcceleration >= ShakerConfigViewModel.Instance.MaxAcceleration;
         public bool DisplacementOverLimit => MaxDisplacement > ShakerConfigViewModel.Instance.MaxDisplacement;
         public bool VelocityOverLimit => MaxVelocity > ShakerConfigViewModel.Instance.MaxVelocity;
-        public float AccelerationLoad => MathF.Round(MaxAcceleration / ShakerConfigViewModel.Instance.MaxAcceleration * 100f, 2);
-        public float DisplacementLoad => MathF.Round((float)MaxDisplacement / ShakerConfigViewModel.Instance.MaxDisplacement * 100f, 2);
-        public float VelocityLoad => MathF.Round((float)MaxVelocity / ShakerConfigViewModel.Instance.MaxVelocity * 100f, 2);
+        public double AccelerationLoad => Math.Round(MaxAcceleration / ShakerConfigViewModel.Instance.MaxAcceleration * 100f, 2);
+        public double DisplacementLoad => Math.Round((double)MaxDisplacement / ShakerConfigViewModel.Instance.MaxDisplacement * 100f, 2);
+        public double VelocityLoad => Math.Round((double)MaxVelocity / ShakerConfigViewModel.Instance.MaxVelocity * 100f, 2);
 
 
-        public float RMSAcceleration { get => rmsAcceleration; set =>SetProperty(ref rmsAcceleration , value); }
+        public double RMSAcceleration { get => rmsAcceleration; set =>SetProperty(ref rmsAcceleration , value); }
 
         public ICommand AddCommand => new RelayCommand(Add);
         private void Add()
@@ -318,20 +318,20 @@ namespace ShakerApp.ViewModels
             if (items.Count < 3) return;
             CalcRefSpectrum(items.Select(x => x.Frequency).ToArray(), items.Select(x => x.Value).ToArray(), items.Select(x => x.ValueType).ToArray(), FrequencyResolution,out var fy_array,out var f,out var turningfreq);
             if (fy_array.Length == 0) return;
-            RMSAcceleration = MathF.Sqrt(ViewModels.MainViewModel.Default.Calc.Sum.Sum(ref fy_array[0], (uint)fy_array.Length) * FrequencyResolution);
+            RMSAcceleration = Math.Sqrt(ViewModels.MainViewModel.Default.Calc.Sum.Sum(ref fy_array[0], (uint)fy_array.Length) * FrequencyResolution);
             ResetRMS = RMSAcceleration;
-            float[] f2 = new float[f.Length];
-            float[] fv = new float[f.Length];
+            double[] f2 = new double[f.Length];
+            double[] fv = new double[f.Length];
             MainViewModel.Default.Calc.Multiply.Multiply(ref f[0], ref f[0], (uint)f.Length,ref f2[0]);
             MainViewModel.Default.Calc.Division.Division(ref fy_array[0],ref  f2[0],  (uint)f.Length,ref fv[0]);
-            float sum = MainViewModel.Default.Calc.Sum.Sum(ref fv[0], (uint)fv.Length);
-            MaxVelocity = MathF.Sqrt((sum - (fv[0] + fv[^1] / 2) / 2) * FrequencyResolution) / (2 * MathF.PI) * Sigma * 9.8f;
+            double sum = MainViewModel.Default.Calc.Sum.Sum(ref fv[0], (uint)fv.Length);
+            MaxVelocity = Math.Sqrt((sum - (fv[0] + fv[^1] / 2) / 2) * FrequencyResolution) / (2 * Math.PI) * Sigma * 9.8f;
             MainViewModel.Default.Calc.Division.Division(ref fv[0], ref f2[0], (uint)f.Length, ref fv[0]);
             sum = MainViewModel.Default.Calc.Sum.Sum(ref fv[0], (uint)fv.Length);
-            MaxDisplacement = MathF.Sqrt((sum - (fv[0] + fv[^1] / 2) / 2) * FrequencyResolution) / (2 * MathF.PI*2*MathF.PI) * Sigma * 9800f;
+            MaxDisplacement = Math.Sqrt((sum - (fv[0] + fv[^1] / 2) / 2) * FrequencyResolution) / (2 * Math.PI*2*Math.PI) * Sigma * 9800f;
             OnPropertyChanged(nameof(MaxAcceleration));
-            float[,] spectrumdata = new float[5, f.Length];
-            Unsafe.CopyBlock(ref Unsafe.As<float,byte>(ref spectrumdata[0, 0]), ref Unsafe.As<float,byte>(ref fy_array[0]), (uint)(Unsafe.SizeOf<float>() * fy_array.Length));
+            double[,] spectrumdata = new double[5, f.Length];
+            Unsafe.CopyBlock(ref Unsafe.As<double, byte>(ref spectrumdata[0, 0]), ref Unsafe.As<double, byte>(ref fy_array[0]), (uint)(Unsafe.SizeOf<double>() * fy_array.Length));
             CalcSpectrum(items, f, fy_array, FrequencyResolution, turningfreq, ref spectrumdata);
             datas.Clear();
             velocitydata.Clear();
@@ -364,14 +364,14 @@ namespace ShakerApp.ViewModels
             DisplacementModel.InvalidatePlot(true);
             CanResetRMS = true;
         }
-        private void CalcSpectrum(List<RandomSpectrumItemModel> models, [In] float[] f, [In] float[] fy_array, [In]float deltaf, [In] float[] turn_freq,ref float[,] spectrumdata)
+        private void CalcSpectrum(List<RandomSpectrumItemModel> models, [In] double[] f, [In] double[] fy_array, [In] double deltaf, [In] double[] turn_freq,ref double[,] spectrumdata)
         {
             CalcItemSpectrum(models.Select(x => x.UpStop).ToArray(), f, fy_array, deltaf, turn_freq, ref spectrumdata[1, 0]);
             CalcItemSpectrum(models.Select(x => x.UpWarn).ToArray(), f, fy_array, deltaf, turn_freq, ref spectrumdata[2, 0]);  
             CalcItemSpectrum(models.Select(x => x.DownStop).ToArray(), f, fy_array, deltaf, turn_freq, ref spectrumdata[3, 0]);
             CalcItemSpectrum(models.Select(x => x.DownWarn).ToArray(), f, fy_array, deltaf, turn_freq, ref spectrumdata[4, 0]);
         }
-        private void CalcItemSpectrum(float[] offset, [In] float[] f, [In] float[] fy_array, [In] float deltaf, [In] float[] turn_freq, ref float spectrumdata)
+        private void CalcItemSpectrum(double[] offset, [In] double[] f, [In] double[] fy_array, [In] double deltaf, [In] double[] turn_freq, ref double spectrumdata)
         {
             for (int i = 0; i < offset.Length - 1; i++)
             {
@@ -379,34 +379,34 @@ namespace ShakerApp.ViewModels
                 uint len = (uint)((turn_freq[i + 1] - turn_freq[i]) / deltaf);
                 if (offset[i+1] == offset[i])
                 {
-                    var x = MathF.Pow(10, offset[i] / 10);
+                    var x = Math.Pow(10, offset[i] / 10);
                     MainViewModel.Default.Calc.Multiply.Multiply(ref fy_array[index], x, len, ref Unsafe.Add(ref spectrumdata,index));
                 }
                 else
                 {
-                    float db1_psd = MathF.Pow(10, offset[i] / 10) * fy_array[index];
-                    float db2_psd = MathF.Pow(10, offset[i + 1] / 10) * fy_array[index+len];
-                    var x= MathF.Log10(db2_psd / db1_psd) / (MathF.Log2(turn_freq[i + 1] / turn_freq[i])) * 10;
+                    double db1_psd = Math.Pow(10, offset[i] / 10) * fy_array[index];
+                    double db2_psd = Math.Pow(10, offset[i + 1] / 10) * fy_array[index+len];
+                    var x= Math.Log10(db2_psd / db1_psd) / (Math.Log2(turn_freq[i + 1] / turn_freq[i])) * 10;
                     for(int j=0;j<len;j++)
                     {
-                        ref float result = ref Unsafe.Add(ref spectrumdata, index + j);
-                       result =  MathF.Pow(10, MathF.Log2(f[index + j] / turn_freq[i]) * x / 10) * db1_psd;
+                        ref double result = ref Unsafe.Add(ref spectrumdata, index + j);
+                       result =  Math.Pow(10, Math.Log2(f[index + j] / turn_freq[i]) * x / 10) * db1_psd;
                     }
                 }
             }
-            ref float temp = ref Unsafe.Add(ref spectrumdata, fy_array.Length - 1);
-            temp = MathF.Pow(10, offset[^1] / 10) * fy_array[^1];
+            ref double temp = ref Unsafe.Add(ref spectrumdata, fy_array.Length - 1);
+            temp = Math.Pow(10, offset[^1] / 10) * fy_array[^1];
         }
-        private void CalcRefSpectrum(float[] f_array, float[] y_array, RandomValueType[] k_array, float deltaf ,out float[] fy_array,out float[] f,out float[] turningfreq)
+        private void CalcRefSpectrum(double[] f_array, double[] y_array, RandomValueType[] k_array, double deltaf ,out double[] fy_array,out double[] f,out double[] turningfreq)
         {
             int n=f_array.Length;
             // 计算圆整频率值及其对应的谱值
-            float[] round_f = new float[n];
-            float[] round_y = new float[n];
-            turningfreq = new float[n];
+            double[] round_f = new double[n];
+            double[] round_y = new double[n];
+            turningfreq = new double[n];
             for (int i = 0; i < n; i++)
             {
-                round_f[i] = MathF.Ceiling(f_array[i] / deltaf) * deltaf;
+                round_f[i] = Math.Ceiling(f_array[i] / deltaf) * deltaf;
                 turningfreq[i] = round_f[i];
             }
 
@@ -424,8 +424,8 @@ namespace ShakerApp.ViewModels
 
             if (k_array[0] ==  RandomValueType.Slope)
             {
-                float kk = y_array[1];
-                y_array[0] = y_array[2] / (MathF.Pow(10, kk / 10 * MathF.Log(f_array[1] / f_array[0], 2)));
+                double kk = y_array[1];
+                y_array[0] = y_array[2] / (Math.Pow(10, kk / 10 * Math.Log(f_array[1] / f_array[0], 2)));
                 y_array[1] = y_array[2];
                 k_array[0] = 0;
                 k_array[1] = 0;
@@ -436,27 +436,27 @@ namespace ShakerApp.ViewModels
             {
                 if (f_array[i] == 0)
                 {
-                    float kk = y_array[i];
+                    double kk = y_array[i];
                     y_array[i] = y_array[i + 1];
-                    f_array[i] = MathF.Pow(2, (10 * MathF.Log(y_array[i + 1] / y_array[i - 1], 10) / kk)) * f_array[i - 1];
+                    f_array[i] = Math.Pow(2, (10 * Math.Log(y_array[i + 1] / y_array[i - 1], 10) / kk)) * f_array[i - 1];
                 }
                 else
                 {
                     if (k_array[i] ==  RandomValueType.Slope)
                     {
-                        y_array[i] = MathF.Pow(10, y_array[i] / 10 * MathF.Log(f_array[i] / f_array[i - 1], 2)) * y_array[i - 1];
+                        y_array[i] = Math.Pow(10, y_array[i] / 10 * Math.Log(f_array[i] / f_array[i - 1], 2)) * y_array[i - 1];
                         k_array[i] = 0;
                     }
                 }
             }
 
             // 验证结果值
-            float[] k_exam = new float[n - 1];
+            double[] k_exam = new double[n - 1];
             for (int i = 0; i < n; i++)
             {
                 if (i < n - 1)
                 {
-                    k_exam[i] = 10 * MathF.Log(y_array[i + 1] / y_array[i], 10) / MathF.Log(f_array[i + 1] / f_array[i], 2);
+                    k_exam[i] = 10 * Math.Log(y_array[i + 1] / y_array[i], 10) / Math.Log(f_array[i + 1] / f_array[i], 2);
                 }
             }
 
@@ -472,24 +472,24 @@ namespace ShakerApp.ViewModels
                 {
                     if (round_f[i] > f_array[i])
                     {
-                        round_y[i] = MathF.Pow(10, k_exam[i] / 10 * MathF.Log(round_f[i] / f_array[i], 2)) * y_array[i];
+                        round_y[i] = Math.Pow(10, k_exam[i] / 10 * Math.Log(round_f[i] / f_array[i], 2)) * y_array[i];
                     }
                 }
 
                 if (i == n - 1)
                 {
-                    round_y[i] = MathF.Pow(10, k_exam[i - 1] / 10 * MathF.Log(round_f[i] / f_array[i], 2)) * y_array[i];
+                    round_y[i] = Math.Pow(10, k_exam[i - 1] / 10 * Math.Log(round_f[i] / f_array[i], 2)) * y_array[i];
                 }
 
                 if (round_f[i] < f_array[i])
                 {
-                    round_y[i] = MathF.Pow(10, k_exam[i - 1] / 10 * MathF.Log(f_array[i] / round_f[i], 2)) * y_array[i];
+                    round_y[i] = Math.Pow(10, k_exam[i - 1] / 10 * Math.Log(f_array[i] / round_f[i], 2)) * y_array[i];
                 }
             }
 
             int parts = k_exam.Length; // 将谱按斜率分成几段,parts为总的段数\
             f = Enumerable.Range(0, (int)((round_f[n - 1] - round_f[0]) / deltaf) + 1).Select(x => x * deltaf + round_f[0]).ToArray();
-            fy_array =new float[f.Length];
+            fy_array =new double[f.Length];
             fy_array[0] = round_y[0];
             fy_array[^1] = round_y[^1];
             int part_begin = 0;
@@ -512,7 +512,7 @@ namespace ShakerApp.ViewModels
                     {
                         for (int k = part_begin + 1; k <= part_begin + n_part; k++)
                         {
-                            fy_array[k] = MathF.Pow(10, k_exam[i] / 10 * MathF.Log(f[k] / f[k - 1], 2)) * fy_array[k - 1];
+                            fy_array[k] = Math.Pow(10, k_exam[i] / 10 * Math.Log(f[k] / f[k - 1], 2)) * fy_array[k - 1];
                         }
                     }
                 }

+ 6 - 6
Avalonia/ShakerApp/ViewModels/ShakerConfig/RandomSpectrumItemViewModel.cs

@@ -13,18 +13,18 @@ namespace ShakerApp.ViewModels
             UpDateModel(model);
         }
         [PropertyAssociation(nameof(RandomSpectrumItemModel.Frequency))]
-        public float Frequency { get => Model.Frequency; set => SetProperty(ref Model.Frequency, value); }
+        public double Frequency { get => Model.Frequency; set => SetProperty(ref Model.Frequency, value); }
         [PropertyAssociation(nameof(RandomSpectrumItemModel.ValueType))]
         public RandomValueType ValueType { get => Model.ValueType; set => SetProperty(ref Model.ValueType, value); }
         [PropertyAssociation(nameof(RandomSpectrumItemModel.Value))]
-        public float Value { get => Model.Value; set => SetProperty(ref Model.Value, value); }
+        public double Value { get => Model.Value; set => SetProperty(ref Model.Value, value); }
         [PropertyAssociation(nameof(RandomSpectrumItemModel.UpStop))]
-        public float UpStop { get => Model.UpStop; set => SetProperty(ref Model.UpStop, value); }
+        public double UpStop { get => Model.UpStop; set => SetProperty(ref Model.UpStop, value); }
         [PropertyAssociation(nameof(RandomSpectrumItemModel.UpWarn))]
-        public float UpWarn { get => Model.UpWarn; set => SetProperty(ref Model.UpWarn, value); }
+        public double UpWarn { get => Model.UpWarn; set => SetProperty(ref Model.UpWarn, value); }
         [PropertyAssociation(nameof(RandomSpectrumItemModel.DownStop))]
-        public float DownStop { get => Model.DownStop; set => SetProperty(ref Model.DownStop, value); }
+        public double DownStop { get => Model.DownStop; set => SetProperty(ref Model.DownStop, value); }
         [PropertyAssociation(nameof(RandomSpectrumItemModel.DownWarn))]
-        public float DownWarn { get => Model.DownWarn; set => SetProperty(ref Model.DownWarn, value); }
+        public double DownWarn { get => Model.DownWarn; set => SetProperty(ref Model.DownWarn, value); }
     }
 }

+ 13 - 13
Avalonia/ShakerApp/ViewModels/ShakerConfig/ShakerConfigViewModel.cs

@@ -13,7 +13,7 @@ namespace ShakerApp.ViewModels
         [PropertyAssociation(nameof(ShakerConfigModel.SynthesisType))]
         public AccelerationSynthesisType SynthesisType { get => Model.SynthesisType; set => SetProperty(ref Model.SynthesisType, value); }
         [PropertyAssociation(nameof(ShakerConfigModel.OutSignalGain))]
-        public float OutSignalGain { get => Model.OutSignalGain; set => SetProperty(ref Model.OutSignalGain, value); }
+        public double OutSignalGain { get => Model.OutSignalGain; set => SetProperty(ref Model.OutSignalGain, value); }
         public override bool CanResize => false;
         public override double Width => 960;
         public override double Height => 560;
@@ -34,7 +34,7 @@ namespace ShakerApp.ViewModels
         [PropertyAssociation(nameof(ShakerConfigModel.StartCount))]
         public uint StartCount => Model.StartCount;
         [PropertyAssociation(nameof(ShakerConfigModel.InitialLocation))]
-        public float InitialLocation { get => Model.InitialLocation; set => SetProperty(ref Model.InitialLocation, value); }
+        public double InitialLocation { get => Model.InitialLocation; set => SetProperty(ref Model.InitialLocation, value); }
         [PropertyAssociation(nameof(ShakerConfigModel.SampleRate))]
         public uint SampleRate => Model.SampleRate;
         [PropertyAssociation(nameof(ShakerConfigModel.FPGAClock))]
@@ -42,30 +42,30 @@ namespace ShakerApp.ViewModels
         [PropertyAssociation(nameof(ShakerConfigModel.AnalogSignalConfigs))]
         public int ChannelCount => Model.AnalogSignalConfigs.Count;
         [PropertyAssociation(nameof(ShakerConfigModel.MaxFrequency))]
-        public float MaxFrequency { get => Model.MaxFrequency; set => SetProperty(ref Model.MaxFrequency, value); }
+        public double MaxFrequency { get => Model.MaxFrequency; set => SetProperty(ref Model.MaxFrequency, value); }
         [PropertyAssociation(nameof(ShakerConfigModel.MinFrequency))]
-        public float MinFrequency { get => Model.MinFrequency; set => SetProperty(ref Model.MinFrequency, value); }
+        public double MinFrequency { get => Model.MinFrequency; set => SetProperty(ref Model.MinFrequency, value); }
         [PropertyAssociation(nameof(ShakerConfigModel.MaxOutInput))]
 
-        public float MaxOutInput { get => Model.MaxOutInput; set => SetProperty(ref Model.MaxOutInput, value); }
+        public double MaxOutInput { get => Model.MaxOutInput; set => SetProperty(ref Model.MaxOutInput, value); }
         [PropertyAssociation(nameof(ShakerConfigModel.MaxAcceleration))]
-        public float MaxAcceleration { get => Model.MaxAcceleration; set => SetProperty(ref Model.MaxAcceleration, value); }
+        public double MaxAcceleration { get => Model.MaxAcceleration; set => SetProperty(ref Model.MaxAcceleration, value); }
         [PropertyAssociation(nameof(ShakerConfigModel.MaxDisplacement))]
-        public float MaxDisplacement { get => Model.MaxDisplacement; set => SetProperty(ref Model.MaxDisplacement, value); }
+        public double MaxDisplacement { get => Model.MaxDisplacement; set => SetProperty(ref Model.MaxDisplacement, value); }
         [PropertyAssociation(nameof(ShakerConfigModel.MaxDriver))]
-        public float MaxDriver { get => Model.MaxDriver; set => SetProperty(ref Model.MaxDriver, value); }
+        public double MaxDriver { get => Model.MaxDriver; set => SetProperty(ref Model.MaxDriver, value); }
         [PropertyAssociation(nameof(ShakerConfigModel.MaxJitterAcceleration))]
-        public float MaxJitterAcceleration { get => Model.MaxJitterAcceleration; set => SetProperty(ref Model.MaxJitterAcceleration, value); }
+        public double MaxJitterAcceleration { get => Model.MaxJitterAcceleration; set => SetProperty(ref Model.MaxJitterAcceleration, value); }
         [PropertyAssociation(nameof(ShakerConfigModel.MaxJitterDisplacement))]
-        public float MaxJitterDisplacement { get => Model.MaxJitterDisplacement; set => SetProperty(ref Model.MaxJitterDisplacement, value); }
+        public double MaxJitterDisplacement { get => Model.MaxJitterDisplacement; set => SetProperty(ref Model.MaxJitterDisplacement, value); }
         [PropertyAssociation(nameof(ShakerConfigModel.MaxVelocity))]
-        public float MaxVelocity { get => Model.MaxVelocity; set => SetProperty(ref Model.MaxVelocity, value); }
+        public double MaxVelocity { get => Model.MaxVelocity; set => SetProperty(ref Model.MaxVelocity, value); }
         [PropertyAssociation(nameof(ShakerConfigModel.AccelerationConfigs))]
         public int AccelerationSensorCount => Model.AccelerationConfigs.Count;
         public AvaloniaList<IndexValueItemViewModel<AnalogSignalConfigViewModel>> AnalogSignals { get; } = new AvaloniaList<IndexValueItemViewModel<AnalogSignalConfigViewModel>>();
         public AvaloniaList<IndexValueItemViewModel<AccelerationConfigViewModel>> Accelerations { get; } = new AvaloniaList<IndexValueItemViewModel<AccelerationConfigViewModel>>();
         [PropertyAssociation(nameof(ShakerConfigModel.DisplacementSensitivity))]
-        public float DisplacementSensitivity { get => Model.DisplacementSensitivity; set => SetProperty(ref Model.DisplacementSensitivity, value); }
+        public double DisplacementSensitivity { get => Model.DisplacementSensitivity; set => SetProperty(ref Model.DisplacementSensitivity, value); }
         private ShakerConfigViewModel()
         {
             
@@ -95,7 +95,7 @@ namespace ShakerApp.ViewModels
                     UpDateModel(args.Data);
                     CommunicationViewModel.Intance.ServiceCommunication?.GetEvent<Shaker.Models.ShakerConfigModel>()?.Publish(this, args.Data);
                 });
-                GetEvent("InitSeries").Publish(this, null);
+                GetEvent(Models.Topic.InitSeries).Publish(this, null);
             });
         }
         static ShakerConfigViewModel()

+ 37 - 37
Avalonia/ShakerApp/ViewModels/ShakerConfig/SweepConfigViewModel.cs

@@ -240,7 +240,7 @@ namespace ShakerApp.ViewModels
             }
         }
         [PropertyAssociation(nameof(SweepConfigModel.StartFrequency))]
-        public float StartFrequency 
+        public double StartFrequency 
         { 
             get => Model.StartFrequency;
             set
@@ -282,17 +282,17 @@ namespace ShakerApp.ViewModels
             })));
             Refresh();
         }
-        public float MaxAcceleration => datas.Count ==0 ?0: datas.Max(x => x.TargetAcceleration);
+        public double MaxAcceleration => datas.Count ==0 ?0: datas.Max(x => x.TargetAcceleration);
         public double MaxDisplacement => displacementdata.Count == 0 ? 0 : displacementdata.Max(x => x.Y);
         public double MaxVelocity => velocitydata.Count == 0 ? 0 : velocitydata.Max(x => x.Y);
         public bool AccelerationOverLimit => MaxAcceleration >= ShakerConfigViewModel.Instance.MaxAcceleration;
         public bool DisplacementOverLimit => MaxDisplacement > ShakerConfigViewModel.Instance.MaxDisplacement;
         public bool VelocityOverLimit => MaxVelocity > ShakerConfigViewModel.Instance.MaxVelocity;
-        public float AccelerationLoad => MathF.Round(MaxAcceleration / ShakerConfigViewModel.Instance.MaxAcceleration * 100f, 2);
-        public float DisplacementLoad => MathF.Round((float)MaxDisplacement / ShakerConfigViewModel.Instance.MaxDisplacement * 100f, 2);
-        public float VelocityLoad => MathF.Round((float)MaxVelocity / ShakerConfigViewModel.Instance.MaxVelocity * 100f, 2);
+        public double AccelerationLoad => Math.Round(MaxAcceleration / ShakerConfigViewModel.Instance.MaxAcceleration * 100f, 2);
+        public double DisplacementLoad => Math.Round((double)MaxDisplacement / ShakerConfigViewModel.Instance.MaxDisplacement * 100f, 2);
+        public double VelocityLoad => Math.Round((double)MaxVelocity / ShakerConfigViewModel.Instance.MaxVelocity * 100f, 2);
         [PropertyAssociation(nameof(SweepConfigModel.EndFrequency))]
-        public float EndFrequency 
+        public double EndFrequency 
         {
             get => Model.EndFrequency;
             set
@@ -304,12 +304,12 @@ namespace ShakerApp.ViewModels
             }
         }
         [PropertyAssociation(nameof(SweepConfigModel.OnceSweepTime))]
-        public float OnceSweepTime 
+        public double OnceSweepTime 
         {
             get => Model.OnceSweepTime;
             set
             {
-                if (MathF.Abs(value - Model.OnceSweepTime) <= Increment || float.IsNaN(value)) return;
+                if (Math.Abs(value - Model.OnceSweepTime) <= Increment || double.IsNaN(value)) return;
                 SetProperty(ref Model.OnceSweepTime, value);
                 OnPropertyChanged(nameof(TotalSweepTime));
                 if (SignalType == SignalType.Fixed) return;
@@ -356,10 +356,10 @@ namespace ShakerApp.ViewModels
                                     case SweepValueType.FixedAcceleration:
                                         break;
                                     case SweepValueType.FixedDisplacement:
-                                        Model.SweepItems[i].Frequency =MathF.Round(MathF.Sqrt(Model.SweepItems[i].Value*9800 / Model.SweepItems[i - 1].Value) / (2 * MathF.PI),2);
+                                        Model.SweepItems[i].Frequency =Math.Round(Math.Sqrt(Model.SweepItems[i].Value*9800 / Model.SweepItems[i - 1].Value) / (2 * Math.PI),2);
                                         break;
                                     case SweepValueType.FixedVelocity:
-                                        Model.SweepItems[i].Frequency = MathF.Round(Model.SweepItems[i].Value * 9.8f / (2 * MathF.PI * Model.SweepItems[i - 1].Value), 2);
+                                        Model.SweepItems[i].Frequency = Math.Round(Model.SweepItems[i].Value * 9.8f / (2 * MathF.PI * Model.SweepItems[i - 1].Value), 2);
                                         break;
                                 }
                             }
@@ -370,10 +370,10 @@ namespace ShakerApp.ViewModels
                                 {
                                     case SweepValueType.DynamicAcceleration:
                                     case SweepValueType.FixedAcceleration:
-                                        Model.SweepItems[i].Frequency = MathF.Round(MathF.Sqrt(Model.SweepItems[i-1].Value * 9800 / Model.SweepItems[i].Value) / (2 * MathF.PI), 2);
+                                        Model.SweepItems[i].Frequency = Math.Round(Math.Sqrt(Model.SweepItems[i-1].Value * 9800 / Model.SweepItems[i].Value) / (2 * Math.PI), 2);
                                         break;
                                     case SweepValueType.FixedVelocity:
-                                        Model.SweepItems[i].Frequency = MathF.Round(Model.SweepItems[i - 1].Value * 1000 / (2 * MathF.PI * Model.SweepItems[i].Value), 2);
+                                        Model.SweepItems[i].Frequency = Math.Round(Model.SweepItems[i - 1].Value * 1000 / (2 * Math.PI * Model.SweepItems[i].Value), 2);
                                         break;
                                     case SweepValueType.FixedDisplacement:
                                         break;
@@ -386,12 +386,12 @@ namespace ShakerApp.ViewModels
                                 {
                                     case SweepValueType.DynamicAcceleration:
                                     case SweepValueType.FixedAcceleration:
-                                        Model.SweepItems[i].Frequency = MathF.Round(Model.SweepItems[i-1].Value * 9.8f / (2 * MathF.PI * Model.SweepItems[i].Value), 2);
+                                        Model.SweepItems[i].Frequency = Math.Round(Model.SweepItems[i-1].Value * 9.8f / (2 * Math.PI * Model.SweepItems[i].Value), 2);
                                         break;
                                     case SweepValueType.FixedVelocity:
                                         break;
                                     case SweepValueType.FixedDisplacement:
-                                        Model.SweepItems[i].Frequency = MathF.Round(Model.SweepItems[i].Value * 1000 / (2 * MathF.PI * Model.SweepItems[i-1].Value), 2);
+                                        Model.SweepItems[i].Frequency = Math.Round(Model.SweepItems[i].Value * 1000 / (2 * Math.PI * Model.SweepItems[i-1].Value), 2);
                                         break;
                                 }
                             }
@@ -414,27 +414,27 @@ namespace ShakerApp.ViewModels
             datas.Clear();
             velocitydata.Clear();
             displacementdata.Clear();
-            int count = (int)MathF.Ceiling((MaxFrequency - MinFrequency) / interval)+1;
+            int count = (int)Math.Ceiling((MaxFrequency - MinFrequency) / interval)+1;
             for(int i=0;i<count;i++)
             {
-                float freq = i * interval + MinFrequency;
-                float acc = 0;
-                float upstop = 0;
-                float upwarn = 0;
-                float downstop = 0;
-                float downwarn = 0;
+                double freq = i * interval + MinFrequency;
+                double acc = 0;
+                double upstop = 0;
+                double upwarn = 0;
+                double downstop = 0;
+                double downwarn = 0;
                 Model.CalcAmpt(freq, ref acc, ref upstop, ref upwarn, ref downstop, ref downwarn);
                 datas.Add(new SweepData()
                 {
                     Frequency =freq,
-                    TargetAcceleration= MathF.Round(acc,4),
+                    TargetAcceleration= Math.Round(acc,4),
                     UpStopAcceleration = upstop,
                     UpWarnAcceleration = upwarn,
                     DownStopAcceleration = downstop,
                     DownWarnAcceleration = downwarn,
                 });
-                velocitydata.Add(new DataPoint(freq,MathF.Round(Shaker.Models.Tools.Tools.AccelerationToVelocity(acc,freq),4)));
-                displacementdata.Add(new DataPoint(freq,MathF.Round(Shaker.Models.Tools.Tools.AccelerationToDisplacement(acc, freq),4)));
+                velocitydata.Add(new DataPoint(freq,Math.Round(Shaker.Models.Tools.Tools.AccelerationToVelocity(acc,freq),4)));
+                displacementdata.Add(new DataPoint(freq,Math.Round(Shaker.Models.Tools.Tools.AccelerationToDisplacement(acc, freq),4)));
             }
             AccelerationModel.InvalidatePlot(false);
             VelocityModel.InvalidatePlot(false);
@@ -462,20 +462,20 @@ namespace ShakerApp.ViewModels
             OnPropertyChanged(nameof(MinFrequency));
         }
         [PropertyAssociation(nameof(SweepConfigModel.SweepSpeed))]
-        public float SweepSpeed 
+        public double SweepSpeed 
         {
             get => Model.SweepSpeed;
             set
             {
-                if (MathF.Abs(value - Model.SweepSpeed)<=Increment || float.IsNaN(value)) return;
+                if (Math.Abs(value - Model.SweepSpeed)<=Increment || double.IsNaN(value)) return;
                 SetProperty(ref Model.SweepSpeed, value);
                 OnceSweepTime = Model.OCTToTime(value);
             }
         }
         [PropertyAssociation(nameof(SweepConfigModel.Increment))]
-        public float Increment => Model.Increment;
+        public double Increment => Model.Increment;
         [PropertyAssociation(nameof(SweepConfigModel.OnceSweepTime),nameof(SweepConfigModel.SweepCount))]
-        public float TotalSweepTime => OnceSweepTime * SweepCount;
+        public double TotalSweepTime => OnceSweepTime * SweepCount;
         [PropertyAssociation(nameof(SweepConfigModel.SweepItems))]
         public bool AddEnabled => SweepItems.Count < MaxSweepItemCount;
         [PropertyAssociation(nameof(SweepConfigModel.SweepItems))]
@@ -484,26 +484,26 @@ namespace ShakerApp.ViewModels
         public bool RefreshEnabled => SweepItems.Count >= 2;
 
         [PropertyAssociation(nameof(SweepConfigModel.SweepStartLevel))]
-        public float SweepStartLevel { get => Model.SweepStartLevel; set => SetProperty(ref Model.SweepStartLevel, value); }
+        public double SweepStartLevel { get => Model.SweepStartLevel; set => SetProperty(ref Model.SweepStartLevel, value); }
         [PropertyAssociation(nameof(SweepConfigModel.CrossoverPoint))]
-        public float CrossoverPoint { get => Model.CrossoverPoint; set => SetProperty(ref Model.CrossoverPoint, value); }
+        public double CrossoverPoint { get => Model.CrossoverPoint; set => SetProperty(ref Model.CrossoverPoint, value); }
         [PropertyAssociation(nameof(SweepConfigModel.SweepLevelGain))]
-        public float SweepLevelGain { get => Model.SweepLevelGain; set => SetProperty(ref Model.SweepLevelGain, value); }
+        public double SweepLevelGain { get => Model.SweepLevelGain; set => SetProperty(ref Model.SweepLevelGain, value); }
         [PropertyAssociation(nameof(SweepConfigModel.LowFrequencyMinCorrect))]
-        public float LowFrequencyMinCorrect { get => Model.LowFrequencyMinCorrect; set => SetProperty(ref Model.LowFrequencyMinCorrect, value); }
+        public double LowFrequencyMinCorrect { get => Model.LowFrequencyMinCorrect; set => SetProperty(ref Model.LowFrequencyMinCorrect, value); }
         [PropertyAssociation(nameof(SweepConfigModel.LowFrequencyMaxCorrect))]
-        public float LowFrequencyMaxCorrect { get => Model.LowFrequencyMaxCorrect; set => SetProperty(ref Model.LowFrequencyMaxCorrect, value); }
+        public double LowFrequencyMaxCorrect { get => Model.LowFrequencyMaxCorrect; set => SetProperty(ref Model.LowFrequencyMaxCorrect, value); }
         [PropertyAssociation(nameof(SweepConfigModel.HigthFrequencyMinCorrect))]
-        public float HigthFrequencyMinCorrect { get => Model.HigthFrequencyMinCorrect; set => SetProperty(ref Model.HigthFrequencyMinCorrect, value); }
+        public double HigthFrequencyMinCorrect { get => Model.HigthFrequencyMinCorrect; set => SetProperty(ref Model.HigthFrequencyMinCorrect, value); }
         [PropertyAssociation(nameof(SweepConfigModel.HigthFrequencyMaxCorrect))]
-        public float HigthFrequencyMaxCorrect { get => Model.HigthFrequencyMaxCorrect; set => SetProperty(ref Model.HigthFrequencyMaxCorrect, value); }
+        public double HigthFrequencyMaxCorrect { get => Model.HigthFrequencyMaxCorrect; set => SetProperty(ref Model.HigthFrequencyMaxCorrect, value); }
         [PropertyAssociation(nameof(SweepConfigModel.SweepItems))]
         public AvaloniaList<IndexValueItemViewModel<SweepItemViewModel>> SweepItems { get; } = new AvaloniaList<IndexValueItemViewModel<SweepItemViewModel>>();
         public ICommand AddCommand => new RelayCommand(Add);
         [PropertyAssociation(nameof(SweepConfigModel.SweepItems))]
-        public float MaxFrequency => SweepItems.Count ==0 ? ShakerConfigViewModel.Instance.MaxFrequency: SweepItems.Max(x=>x.Value.Frequency);
+        public double MaxFrequency => SweepItems.Count ==0 ? ShakerConfigViewModel.Instance.MaxFrequency: SweepItems.Max(x=>x.Value.Frequency);
         [PropertyAssociation(nameof(SweepConfigModel.SweepItems))]
-        public float MinFrequency => SweepItems.Count ==0 ? ShakerConfigViewModel.Instance.MinFrequency: SweepItems.Min(x => x.Value.Frequency);
+        public double MinFrequency => SweepItems.Count ==0 ? ShakerConfigViewModel.Instance.MinFrequency: SweepItems.Min(x => x.Value.Frequency);
         private void Add()
         {
             if (SweepItems.Count >= MaxSweepItemCount) return;

+ 7 - 7
Avalonia/ShakerApp/ViewModels/ShakerConfig/SweepData.cs

@@ -2,12 +2,12 @@
 {
     public class SweepData
     {
-        public float Frequency { get; set; } = float.NaN;
-        public float Acceleration { get; set; } = float.NaN;
-        public float TargetAcceleration { get; set; } = float.NaN;
-        public float UpStopAcceleration { get; set; } = float.NaN;
-        public float DownStopAcceleration { get; set; } = float.NaN;
-        public float UpWarnAcceleration { get; set; } = float.NaN;
-        public float DownWarnAcceleration { get; set; } = float.NaN;
+        public double Frequency { get; set; } = double.NaN;
+        public double Acceleration { get; set; } = double.NaN;
+        public double TargetAcceleration { get; set; } = double.NaN;
+        public double UpStopAcceleration { get; set; } = double.NaN;
+        public double DownStopAcceleration { get; set; } = double.NaN;
+        public double UpWarnAcceleration { get; set; } = double.NaN;
+        public double DownWarnAcceleration { get; set; } = double.NaN;
     }
 }

+ 6 - 6
Avalonia/ShakerApp/ViewModels/ShakerConfig/SweepItemViewModel.cs

@@ -20,16 +20,16 @@ namespace ShakerApp.ViewModels
         [PropertyAssociation(nameof(SweepItemModel.SweepValueType))]
         public SweepValueType SweepValueType { get => Model.SweepValueType; set => SetProperty(ref Model.SweepValueType, value); }
         [PropertyAssociation(nameof(SweepItemModel.Value))]
-        public float Value { get => Model.Value; set => SetProperty(ref Model.Value, value); }
+        public double Value { get => Model.Value; set => SetProperty(ref Model.Value, value); }
         [PropertyAssociation(nameof(SweepItemModel.Frequency))]
-        public float Frequency { get =>Math.Clamp(Model.Frequency,ShakerConfigViewModel.Instance.MinFrequency,ShakerConfigViewModel.Instance.MaxFrequency) ; set => SetProperty(ref Model.Frequency,Math.Clamp(value,ShakerConfigViewModel.Instance.MinFrequency,ShakerConfigViewModel.Instance.MaxFrequency)); }
+        public double Frequency { get =>Math.Clamp(Model.Frequency,ShakerConfigViewModel.Instance.MinFrequency,ShakerConfigViewModel.Instance.MaxFrequency) ; set => SetProperty(ref Model.Frequency,Math.Clamp(value,ShakerConfigViewModel.Instance.MinFrequency,ShakerConfigViewModel.Instance.MaxFrequency)); }
         [PropertyAssociation(nameof(SweepItemModel.UpStop))]
-        public float UpStop { get => Model.UpStop; set => SetProperty(ref Model.UpStop, value); }
+        public double UpStop { get => Model.UpStop; set => SetProperty(ref Model.UpStop, value); }
         [PropertyAssociation(nameof(SweepItemModel.UpWarn))]
-        public float UpWarn { get => Model.UpWarn; set => SetProperty(ref Model.UpWarn, value); }
+        public double UpWarn { get => Model.UpWarn; set => SetProperty(ref Model.UpWarn, value); }
         [PropertyAssociation(nameof(SweepItemModel.DownStop))]
-        public float DownStop { get => Model.DownStop; set => SetProperty(ref Model.DownStop, value); }
+        public double DownStop { get => Model.DownStop; set => SetProperty(ref Model.DownStop, value); }
         [PropertyAssociation(nameof(SweepItemModel.DownWarn))]
-        public float DownWarn { get => Model.DownWarn; set => SetProperty(ref Model.DownWarn, value); }
+        public double DownWarn { get => Model.DownWarn; set => SetProperty(ref Model.DownWarn, value); }
     }
 }

+ 14 - 3
Avalonia/ShakerApp/ViewModels/ShakerControl/ShakerControlViewModel.cs

@@ -21,7 +21,7 @@ namespace ShakerApp.ViewModels
         }
         private ShakerControlViewModel()
         {
-            for (int i = 0; i < ServoValveCount; i++)
+            for (int i = 0; i < Model.ValveConfig.Count; i++)
             {
                 ValveConfig.Add(new IndexValueItemViewModel<ValveConfigItemViewModel>(i + 1, new ValveConfigItemViewModel(Model.ValveConfig[i])));
             }
@@ -63,7 +63,15 @@ namespace ShakerApp.ViewModels
             }
         }
         [PropertyAssociation(nameof(ShakerControlModel.PageType))]
-        public MainPageType PageType { get => Model.PageType; set => SetProperty(ref Model.PageType, value); }
+        public MainPageType PageType
+        { 
+            get => Model.PageType;
+            set
+            {
+                SetProperty(ref Model.PageType, value);
+                CommunicationViewModel.Intance.LocalCommunication?.GetEvent<ShakerControlModel>()?.Publish(this, Model);
+            }
+        }
         [PropertyAssociation(nameof(ShakerControlModel.MaxControlItemCount))]
         public int MaxControlItemCount => Model.MaxControlItemCount;
         [PropertyAssociation(nameof(ShakerControlModel.MaxDisplacementVoltage))]
@@ -112,12 +120,15 @@ namespace ShakerApp.ViewModels
         private void Add()
         {
             if (ControlItems.Count >= MaxControlItemCount) return;
-            ControlItems.Add(new IndexValueItemViewModel<SweepControlItemViewModel>(ControlItems.Count + 1, new SweepControlItemViewModel()));
+            SaveIsEnabled = true;
+            Model.ControlItems.Add(new SweepControlItemModel());
+            ControlItems.Add(new IndexValueItemViewModel<SweepControlItemViewModel>(ControlItems.Count + 1,new SweepControlItemViewModel( Model.ControlItems[^1])));
         }
         public ICommand DeleteLastCommand => new CommunityToolkit.Mvvm.Input.RelayCommand(Delete);
         private void Delete()
         {
             if (ControlItems.Count == 0) return;
+            Model.ControlItems.RemoveAt(Model.ControlItems.Count - 1);
             ControlItems.RemoveAt(ControlItems.Count - 1);
         }
         public ICommand RefreshCommand => new CommunityToolkit.Mvvm.Input.RelayCommand(Refresh);

+ 2 - 2
Avalonia/ShakerApp/ViewModels/ShakerControl/ValveConfigItemViewModel.cs

@@ -14,8 +14,8 @@ namespace ShakerApp.ViewModels
 
         }
         [PropertyAssociation(nameof(ValveConfigItemModel.Bias))]
-        public float Bias { get => Model.Bias; set => SetProperty(ref Model.Bias, value); }
+        public double Bias { get => Model.Bias; set => SetProperty(ref Model.Bias, value); }
         [PropertyAssociation(nameof(ValveConfigItemModel.OpenLoopDrive))]
-        public float OpenLoopDrive { get => Model.OpenLoopDrive; set => SetProperty(ref Model.OpenLoopDrive, value); }
+        public double OpenLoopDrive { get => Model.OpenLoopDrive; set => SetProperty(ref Model.OpenLoopDrive, value); }
     }
 }

+ 3 - 1
Avalonia/ShakerApp/ViewModels/ShakerDataViewModel.cs

@@ -55,12 +55,13 @@ namespace ShakerApp.ViewModels
                     List<DataPoint> dataPoints = new List<DataPoint>();
                     float max = float.MinValue;
                     float min = float.MaxValue;
-                    
+                    float v = 0;
                     for (int j= 0; j < _Data.GetLength(1); j++)
                     {
                         dataPoints.Add(new DataPoint(1.0 / ShakerConfigViewModel.Instance.SampleRate * j, _Data[i, j]));
                         max = _Data[i, j] > max ? _Data[i, j] : max;
                         min = _Data[i, j] < min ? _Data[i, j] : min;
+                        v += _Data[i, j];
                     }
                     Models.StatisticsModel model = new Models.StatisticsModel()
                     {
@@ -68,6 +69,7 @@ namespace ShakerApp.ViewModels
                         Max = max,
                         Min = min,
                         RMS = MainViewModel.Default.Calc.Sum.Rms(ref _Data[i, 0], (uint)_Data.GetLength(1)),
+                        Average = v/ _Data.GetLength(1),
                         Unit = ShakerConfigViewModel.Instance.Model.AnalogSignalConfigs[i].Unit,
                     };
                     if (AnalogDataCache.TryGetValue(ShakerConfigViewModel.Instance.Model.AnalogSignalConfigs[i].AnalogType,out var list))

+ 11 - 166
Avalonia/ShakerApp/ViewModels/ShakerStatus/ShakerStatusViewModel.cs

@@ -19,8 +19,6 @@ namespace ShakerApp.ViewModels
 {
     public sealed class ShakerStatusViewModel:ViewModelBase<ShakerStatusModel>
     {
-        List<OxyPlot.Series.LineSeries> displineSeries = new List<OxyPlot.Series.LineSeries>();
-        List<OxyPlot.Series.LineSeries> driverlineSeries = new List<OxyPlot.Series.LineSeries>();
         private float givenDisplacement;
         private float measuredDisplacement;
         private float acceleration;
@@ -32,9 +30,15 @@ namespace ShakerApp.ViewModels
         public float Acceleration { get => acceleration; set => SetProperty(ref acceleration, value); }
         public float ValveDrive { get => valveDrive; set => SetProperty(ref valveDrive, value); }
         public float OutSignal { get => outSignal; set => SetProperty(ref outSignal, value); }
+        public ViewModels.AnalogSignalPreviewViewModel DisplacementSignal { get; } = new AnalogSignalPreviewViewModel(AnalogType.Displacement)
+        {
+            CanChangedAnalog = false,
+        };
+        public AnalogSignalPreviewViewModel ValveDriveSignal { get; } = new AnalogSignalPreviewViewModel(AnalogType.Driver)
+        {
+            CanChangedAnalog = false,
+        };
         private float workPosition = 0;
-        private bool displacementStatisticsVisibily = true;
-        private bool servoValveStatisticsVisibily = true;
         private bool valvePower = false;
 
         [PropertyAssociation(nameof(ShakerStatusModel.RTStatus))]
@@ -47,8 +51,8 @@ namespace ShakerApp.ViewModels
         public bool SignalStartEnabled => RTStatus == RTStatus.WaitSignalGen;
         [PropertyAssociation(nameof(ShakerStatusModel.RTStatus))]
         public bool SignalStopEnabled => RTStatus == RTStatus.SignalGen;
-        [PropertyAssociation(nameof(ShakerStatusModel.RTStatus))]
-        public bool RestEnabeld => RTStatus == RTStatus.Error;
+        [PropertyAssociation(nameof(ShakerStatusModel.ErrorCode))]
+        public bool RestEnabeld => ErrorCode!=0;
 
         [PropertyAssociation(nameof(ShakerStatusModel.RTStatus))]
         public RTStatus RTStatus { get => Model.RTStatus; set => SetProperty(ref Model.RTStatus, value); }
@@ -78,10 +82,6 @@ namespace ShakerApp.ViewModels
         public uint DropCount { get => Model.DropCount; set => SetProperty(ref Model.DropCount, value); }
         [PropertyAssociation(nameof(ShakerStatusModel.ErrorCode))]
         public ushort ErrorCode { get => Model.ErrorCode; set => SetProperty(ref Model.ErrorCode, value); }
-        public AvaloniaList<StatisticsViewModel> DisplacementStatistics { get; } = new AvaloniaList<StatisticsViewModel>();
-        public AvaloniaList<StatisticsViewModel> ServoValveStatistics { get; } = new AvaloniaList<StatisticsViewModel>();
-        public bool DisplacementStatisticsVisibily { get => displacementStatisticsVisibily; set =>SetProperty(ref displacementStatisticsVisibily ,value); }
-        public bool ServoValveStatisticsVisibily { get => servoValveStatisticsVisibily; set =>SetProperty(ref servoValveStatisticsVisibily , value); }
         public float WorkPosition 
         { 
             get => workPosition;
@@ -95,18 +95,6 @@ namespace ShakerApp.ViewModels
         {
             Content = typeof(Views.ShakerStatusControlView);
             ButtonVisibily = false;
-            InitDisplacementModel();
-            InitServoValveModel();
-            GetEvent(ShakerSettingViewModel.LANGUAGECHANGEDEVENT).Subscrip((_, _) =>
-            {
-                DisplacementModel.Axes[0].Title = App.Current?.FindResource("Time") + "";
-                DisplacementModel.Axes[1].Title = App.Current?.FindResource("Ampt") + "";
-                DisplacementModel.Title = App.Current?.FindResource("Displacement") + "";
-
-                ServoValveModel.Axes[0].Title = App.Current?.FindResource("Time") + "";
-                ServoValveModel.Axes[1].Title = App.Current?.FindResource("Ampt") + "";
-                ServoValveModel.Title = App.Current?.FindResource("ValveDriveSignal") + "";
-            });
             GetEvent<AllConfig>().Subscrip((sender, args) =>
             {
                 valvePower = false;
@@ -121,62 +109,19 @@ namespace ShakerApp.ViewModels
                     CommunicationViewModel.Intance.ServiceCommunication?.GetEvent<ShakerStatusModel>()?.Publish(this, args.Data);
                 });
             });
-            GetEvent("InitSeries").Subscrip((_, _) =>
-            {
-                InitDisplacementSeries();
-                InitServoValveSeries();
-            });
             GetEvent(Topic.DATA).Subscrip((_, _) =>
             {
-                DisplacementModel.InvalidatePlot(false);
-                ServoValveModel.InvalidatePlot(false);
                 var data = ShakerDataViewModel.Instance.GetAnalogData(AnalogType.Displacement);
                 GivenDisplacement = data[0].Item2.RMS;
                 MeasuredDisplacement = data[1].Item2.RMS;
-                for(int i=0;i<displineSeries.Count;i++)
-                {
-                    displineSeries[i].ItemsSource = data[i].Item1;
-                    DisplacementStatistics[i].UpDateModel(data[i].Item2);
-                }
                 data = ShakerDataViewModel.Instance.GetAnalogData(AnalogType.Driver);
                 ValveDrive = data[0].Item2.RMS;
-                for(int i=0;i<driverlineSeries.Count;i++)
-                {
-                    driverlineSeries[i].ItemsSource = data[i].Item1;
-                    ServoValveStatistics[i].UpDateModel(data[i].Item2);
-                }
-                DisplacementModel.InvalidatePlot(true);
-                ServoValveModel.InvalidatePlot(true);
                 data = ShakerDataViewModel.Instance.GetAnalogData(AnalogType.OutSignal);
                 OutSignal = data[0].Item2.RMS;
                 data = ShakerDataViewModel.Instance.GetAnalogData(AnalogType.Acceleration);
                 Acceleration = data[0].Item2.RMS;
             });
         }
-        private void InitDisplacementSeries()
-        {
-            DisplacementStatistics.Clear();
-            displineSeries.Clear();
-            DisplacementModel.InvalidatePlot(false);
-            DisplacementModel.Series.Clear();
-            ShakerConfigViewModel.Instance.Model.AnalogSignalConfigs.Where(x=>x.AnalogType == AnalogType.Displacement).ToList().ForEach(x =>
-            {
-                LineSeries lineSeries = new LineSeries();
-                lineSeries.DataFieldX = nameof(DataPoint.X);
-                lineSeries.DataFieldY = nameof(DataPoint.Y);
-                lineSeries.XAxisKey = "X";
-                lineSeries.YAxisKey = "Y";
-                lineSeries.Title = App.Current?.FindResource(x.Name) + "";
-                DisplacementStatistics.Add(new StatisticsViewModel(new Models.StatisticsModel()
-                {
-                    Unit = x.Unit,
-                    Name = x.Name,
-                }));
-                displineSeries.Add(lineSeries);
-                DisplacementModel.Series.Add(lineSeries);
-            });
-            DisplacementModel.InvalidatePlot(true);
-        }
         protected override void RefreshUI(List<string> changedNames)
         {
             base.RefreshUI(changedNames);
@@ -190,84 +135,6 @@ namespace ShakerApp.ViewModels
                 OnPropertyChanged(nameof(RestEnabeld));
             }
         }
-        private void InitDisplacementModel()
-        {
-            DisplacementModel.Axes.Add(new OxyPlot.Axes.LinearAxis()
-            {
-                MaximumPadding = 0,
-                MinimumPadding = 0,
-                Title = App.Current?.FindResource("Time") + "",
-                Unit="s",
-                Key = "X",
-                MajorGridlineStyle = OxyPlot.LineStyle.Solid,
-                Position = OxyPlot.Axes.AxisPosition.Bottom
-            });
-            DisplacementModel.Axes.Add(new OxyPlot.Axes.LinearAxis()
-            {
-                Title = App.Current?.FindResource("Ampt") + "",
-                Unit = "mm",
-                Key = "Y",
-                Position = OxyPlot.Axes.AxisPosition.Left,
-                MajorGridlineStyle = OxyPlot.LineStyle.Solid,
-            });
-            DisplacementModel.Title = App.Current?.FindResource("Displacement") + "";
-            DisplacementModel.Legends.Add(new OxyPlot.Legends.Legend()
-            {
-                ShowInvisibleSeries = true,
-            });
-            DisplacementController.BindMouseWheel(OxyMouseWheelCommand);
-        }
-        private void InitServoValveSeries()
-        {
-            ServoValveStatistics.Clear();
-            driverlineSeries.Clear();
-            ServoValveModel.InvalidatePlot(false);
-            ServoValveModel.Series.Clear();
-            ShakerConfigViewModel.Instance.Model.AnalogSignalConfigs.Where(x => x.AnalogType == AnalogType.Driver).ToList().ForEach(x =>
-            {
-                LineSeries lineSeries = new LineSeries();
-                lineSeries.DataFieldX = nameof(DataPoint.X);
-                lineSeries.DataFieldY = nameof(DataPoint.Y);
-                lineSeries.XAxisKey = "X";
-                lineSeries.YAxisKey = "Y";
-                lineSeries.Title = App.Current?.FindResource(x.Name) + "";
-                ServoValveStatistics.Add(new StatisticsViewModel(new Models.StatisticsModel()
-                {
-                    Name = x.Name,
-                    Unit = x.Unit,
-                }));
-                driverlineSeries.Add(lineSeries);
-                ServoValveModel.Series.Add(lineSeries);
-            });
-            ServoValveModel.InvalidatePlot(true);
-        }
-        private void InitServoValveModel()
-        {
-            ServoValveModel.Axes.Add(new OxyPlot.Axes.LinearAxis()
-            {
-                MaximumPadding = 0,
-                MinimumPadding = 0,
-                Title = App.Current?.FindResource("Time") + "",
-                Unit = "s",
-                Key= "X",
-                MajorGridlineStyle = OxyPlot.LineStyle.Solid,
-                Position= OxyPlot.Axes.AxisPosition.Bottom
-            });
-            ServoValveModel.Axes.Add(new OxyPlot.Axes.LinearAxis()
-            {
-                Title = App.Current?.FindResource("Ampt") + "",
-                Unit = "V",
-                Key = "Y",
-                MajorGridlineStyle = OxyPlot.LineStyle.Solid,
-                Position = OxyPlot.Axes.AxisPosition.Left,
-            });
-            ServoValveModel.Title = App.Current?.FindResource("ValveDriveSignal") + "";
-            ServoValveModel.Legends.Add(new OxyPlot.Legends.Legend()
-            {
-                ShowInvisibleSeries = true,
-            });
-            ServoValveController.BindMouseWheel(OxyMouseWheelCommand);
-        }
         public override bool CanCancel => false;
         static ShakerStatusViewModel()
         {
@@ -308,29 +175,7 @@ namespace ShakerApp.ViewModels
 
         public static ShakerStatusViewModel Instance { get; } = new ShakerStatusViewModel();
 
-        public OxyPlot.PlotController DisplacementController { get; } = new PlotController();
-        public OxyPlot.PlotModel DisplacementModel { get; } = new OxyPlot.PlotModel();
-        public OxyPlot.PlotModel ServoValveModel { get; } = new OxyPlot.PlotModel();
-        public PlotController ServoValveController { get; } = new PlotController();
-        public IViewCommand<OxyMouseWheelEventArgs> OxyMouseWheelCommand => new DelegatePlotCommand<OxyMouseWheelEventArgs>(OnOxyMouseWheel);
-        private void OnOxyMouseWheel(IPlotView view,IController controller,OxyMouseWheelEventArgs args)
-        {
-            HandleZoomByWheel(view, args);
-            if(view.ActualModel is PlotModel plotModel && plotModel.Axes.Count>=1 && plotModel.Axes[0] is LinearAxis axis)
-            {
-                axis.MajorStep = (axis.Maximum - axis.Minimum) / 10;
-            }
-        }
-        private void HandleZoomByWheel(IPlotView view, OxyMouseWheelEventArgs args, double factor = 1)
-        {
-            var m = new ZoomStepManipulator(view)
-            {
-                AxisPreference = AxisPreference.X,
-                Step = args.Delta * 0.001 * factor,
-                FineControl = args.IsControlDown,
-            };
-            m.Started(args);
-        }
+       
         public bool ValvePower 
         { 
             get => valvePower;

+ 182 - 0
Avalonia/ShakerApp/ViewModels/SignalPreview/AnalogSignalPreviewViewModel.cs

@@ -0,0 +1,182 @@
+using Avalonia.Collections;
+using Avalonia.Controls;
+using OxyPlot;
+using OxyPlot.Axes;
+using Shaker.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ShakerApp.Tools;
+using OxyPlot.Series;
+
+namespace ShakerApp.ViewModels
+{
+    public class AnalogSignalPreviewViewModel:ViewModelBase<IModel>,IDataPreview
+    {
+        List<OxyPlot.Series.LineSeries> lineSeries = new List<OxyPlot.Series.LineSeries>();
+        private object locker = new object();
+        public AvaloniaList<KeyValuePair<string, AnalogType>> AllAnalogTypes { get; } = new AvaloniaList<KeyValuePair<string, AnalogType>>();
+        public AvaloniaList<ViewModels.StatisticsViewModel> Statistics { get; } = new AvaloniaList<StatisticsViewModel>();
+        private AnalogType selectedAnalog;
+        private bool canChangedAnalog = true;
+        public bool StatisticsVisibily { get => statisticsVisibily; set =>SetProperty(ref statisticsVisibily , value); }
+        public AnalogSignalPreviewViewModel():base()
+        {
+            Content = typeof(Views.AnalogSignalPreviewView);
+            PlotModel.Axes.Add(new OxyPlot.Axes.LinearAxis()
+            {
+                MaximumPadding = 0,
+                MinimumPadding = 0,
+                Title = App.Current?.FindResource("Time") + "",
+                Unit = "s",
+                Key = "X",
+                MajorGridlineStyle = OxyPlot.LineStyle.Solid,
+                Position = OxyPlot.Axes.AxisPosition.Bottom
+            });
+            PlotModel.Axes.Add(new OxyPlot.Axes.LinearAxis()
+            {
+                Title = App.Current?.FindResource("Ampt") + "",
+                Unit = "V",
+                Key = "Y",
+                MajorGridlineStyle = OxyPlot.LineStyle.Solid,
+                Position = OxyPlot.Axes.AxisPosition.Left,
+            });
+            PlotModel.Title = App.Current?.FindResource("ValveDriveSignal") + "";
+            PlotModel.Legends.Add(new OxyPlot.Legends.Legend()
+            {
+                ShowInvisibleSeries = true,
+            });
+            PlotController.BindMouseWheel(OxyMouseWheelCommand);
+            GetEvent(Topic.DATA).Subscrip((_, _) =>
+            {
+                if (!UpSignalData) return;
+                lock(locker)
+                {
+                    if(SelectedAnalog == AnalogType.Driver)
+                    {
+
+                    }
+                    var data = ShakerDataViewModel.Instance.GetAnalogData(SelectedAnalog);
+                    PlotModel.InvalidatePlot(false);
+                    for(int i=0;i<data.Count;i++)
+                    {
+                        lineSeries[i].ItemsSource = data[i].Item1;
+                        Statistics[i].UpDateModel(data[i].Item2);
+                    }
+                    PlotModel.InvalidatePlot(true);
+                }
+            });
+            GetEvent(Models.Topic.InitSeries).Subscrip((_, _) =>
+            {
+                lock(locker)
+                {
+                    AllAnalogTypes.Clear();
+                    ShakerConfigViewModel.Instance.AnalogSignals.ToList()
+                        .ForEach(x =>
+                        {
+                            AllAnalogTypes.Add(new KeyValuePair<string, AnalogType>(x.Value.AnalogType.Description(), x.Value.AnalogType));
+                        });
+                    if (CanChangedAnalog)
+                    {
+                        int index = AllAnalogTypes.ToList().FindIndex(x => x.Value == lasttype);
+                        if (index == -1)
+                        {
+                            SelectedAnalog = AllAnalogTypes.First().Value;
+                        }
+                        else
+                        {
+                            SelectedAnalog = lasttype;
+                        }
+                    }
+                    else
+                    {
+                        SelectedAnalog = lasttype;
+                    }
+                }
+            });
+        }
+        private AnalogType lasttype = AnalogType.Displacement;
+        private bool statisticsVisibily = true;
+
+        public AnalogSignalPreviewViewModel(Shaker.Models.AnalogType analogType):this()
+        {
+            lasttype = analogType;
+        }
+        public AnalogType SelectedAnalog
+        {
+            get => selectedAnalog;
+            set
+            {
+                SetProperty(ref selectedAnalog, value);
+                ChangeAnalogType(value);
+            }
+        }
+        public bool UpSignalData { get; set; } = true;
+        private void ChangeAnalogType(AnalogType type)
+        {
+            lock(locker)
+            {
+                lineSeries.Clear();
+                PlotModel.Series.Clear();
+                Statistics.Clear();
+                var config = ShakerConfigViewModel.Instance.Model.AnalogSignalConfigs.First(x => x.AnalogType == type);
+                PlotModel.Axes[1].Unit = config.Unit;
+                int count = ShakerConfigViewModel.Instance.Model.AnalogSignalConfigs.Count(x => x.AnalogType == type);
+                var data = ShakerDataViewModel.Instance.GetAnalogData(type);
+                for(int i=0;i<count;i++)
+                {
+                    LineSeries series = new LineSeries();
+                    series.Title = App.Current?.FindResource(config.Name) + "";
+                    series.XAxisKey = "X";
+                    series.YAxisKey = "Y";
+                    series.DataFieldX = nameof(DataPoint.X);
+                    series.DataFieldY = nameof(DataPoint.Y);
+                    if(data.Count==count)
+                    {
+                        Statistics.Add(new StatisticsViewModel(data[i].Item2));
+                        series.ItemsSource = data[i].Item1;
+                    }
+                    else
+                    {
+                        Statistics.Add(new StatisticsViewModel());
+                    }
+                    lineSeries.Add(series);
+                }
+                PlotModel.InvalidatePlot(false);
+                PlotModel.Title = App.Current?.FindResource(type.Description()) + "";
+                lineSeries.ForEach(x => PlotModel.Series.Add(x));
+                PlotModel.InvalidatePlot(true);
+            }
+        }
+        public bool CanChangedAnalog
+        {
+            get => canChangedAnalog;
+            set =>SetProperty(ref canChangedAnalog , value); 
+        }
+
+        public OxyPlot.PlotModel PlotModel { get; } = new OxyPlot.PlotModel();
+        public OxyPlot.PlotController PlotController { get; } = new OxyPlot.PlotController();
+        public IViewCommand<OxyMouseWheelEventArgs> OxyMouseWheelCommand => new DelegatePlotCommand<OxyMouseWheelEventArgs>(OnOxyMouseWheel);
+        private void OnOxyMouseWheel(IPlotView view, IController controller, OxyMouseWheelEventArgs args)
+        {
+            HandleZoomByWheel(view, args);
+            if (view.ActualModel is PlotModel plotModel && plotModel.Axes.Count >= 1 && plotModel.Axes[0] is LinearAxis axis)
+            {
+                axis.MajorStep = (axis.Maximum - axis.Minimum) / 10;
+            }
+        }
+        private void HandleZoomByWheel(IPlotView view, OxyMouseWheelEventArgs args, double factor = 1)
+        {
+            var m = new ZoomStepManipulator(view)
+            {
+                AxisPreference = AxisPreference.X,
+                Step = args.Delta * 0.001 * factor,
+                FineControl = args.IsControlDown,
+            };
+            m.Started(args);
+        }
+
+    }
+}

+ 27 - 3
Avalonia/ShakerApp/ViewModels/SignalPreview/SignalPreviewViewModel.cs

@@ -1,4 +1,5 @@
-using Shaker.Models;
+using Avalonia.Collections;
+using Shaker.Models;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -7,16 +8,39 @@ using System.Threading.Tasks;
 
 namespace ShakerApp.ViewModels
 {
-    internal class SignalPreviewViewModel:ViewModelBase<IModel>
+    internal class SignalPreviewViewModel:ViewModelBase<IModel>, IDataPreview
     {
+        public AvaloniaList<AnalogSignalPreviewViewModel> SignalPreviews { get; } = new AvaloniaList<AnalogSignalPreviewViewModel>();
+        private bool upSignalData;
+        private int rowCount = 1;
+        private int columnCount = 1;
+
         private SignalPreviewViewModel()
         {
             Content = typeof(Views.SignalPreviewView);
+            SignalPreviews.Add(new AnalogSignalPreviewViewModel(AnalogType.Displacement));
+            SignalPreviews.Add(new AnalogSignalPreviewViewModel(AnalogType.Acceleration));
+            SignalPreviews.Add(new AnalogSignalPreviewViewModel(AnalogType.OutSignal));
+            SignalPreviews.Add(new AnalogSignalPreviewViewModel(AnalogType.Driver));
         }
         static SignalPreviewViewModel()
         {
 
         }
-        public static SignalPreviewViewModel Instance { get; } = new SignalPreviewViewModel(); 
+        public int RowCount { get => rowCount; set =>SetProperty(ref rowCount , value); }
+        public int ColumnCount { get => columnCount; set =>SetProperty(ref columnCount , value); }
+        public static SignalPreviewViewModel Instance { get; } = new SignalPreviewViewModel();
+        public bool UpSignalData 
+        { 
+            get => upSignalData;
+            set
+            {
+                upSignalData = value;
+                foreach (var item in SignalPreviews)
+                {
+                    item.UpSignalData = value;
+                }
+            }
+        }
     }
 }

+ 3 - 0
Avalonia/ShakerApp/ViewModels/StatisticsViewModel.cs

@@ -26,6 +26,9 @@ namespace ShakerApp.ViewModels
         public float Min { get => Model.Min; set =>SetProperty(ref Model.Min, value); }
         [PropertyAssociation(nameof(StatisticsModel.RMS))]
         public float RMS { get => Model.RMS; set =>SetProperty(ref Model.RMS , value); }
+
+        [PropertyAssociation(nameof(StatisticsModel.Average))]
+        public float Average { get => Model.Average; set => SetProperty(ref Model.Average, value); }
         [PropertyAssociation(nameof(StatisticsModel.Unit))]
         public string Unit { get => Model.Unit; set =>SetProperty(ref Model.Unit , value); }
         public override void UpDateModel(StatisticsModel model)

+ 20 - 6
Avalonia/ShakerApp/Views/DebugView/DebugView.axaml

@@ -183,12 +183,26 @@
                     Height="160"
                     VerticalAlignment="Top">
                     <suki:GroupBox Header="{DynamicResource DebugConfig}">
-                        <StackPanel VerticalAlignment="Top" Orientation="Horizontal">
-                            <TextBlock
-                                HorizontalAlignment="Center"
-                                VerticalAlignment="Center"
-                                Text="{DynamicResource SelfCloseLoop}" />
-                            <ToggleSwitch IsChecked="{Binding SelfLoop}" />
+                        <StackPanel Orientation="Vertical">
+
+                            <StackPanel VerticalAlignment="Top" Orientation="Horizontal">
+                                <TextBlock
+                                    HorizontalAlignment="Center"
+                                    VerticalAlignment="Center"
+                                    Text="{DynamicResource SelfCloseLoop}" />
+                                <ToggleSwitch IsChecked="{Binding SelfLoop}" />
+                            </StackPanel>
+
+                            <StackPanel
+                                Margin="0,10,0,0"
+                                VerticalAlignment="Top"
+                                Orientation="Horizontal">
+                                <TextBlock
+                                    HorizontalAlignment="Center"
+                                    VerticalAlignment="Center"
+                                    Text="Debug" />
+                                <ToggleSwitch IsChecked="{Binding Debug}" />
+                            </StackPanel>
                         </StackPanel>
                     </suki:GroupBox>
                 </suki:GlassCard>

+ 8 - 0
Avalonia/ShakerApp/Views/MainPage/SineMainPage.axaml

@@ -60,6 +60,14 @@
                                 FontWeight="Normal"
                                 Text="{Binding CurrentAcceleration, StringFormat='{}{0:F2} g'}" />
                         </StackPanel>
+                        <StackPanel Height="{StaticResource ItemHeight}" Orientation="Horizontal">
+
+                            <TextBlock VerticalAlignment="Center" Text="当前阶段:" />
+                            <TextBlock
+                                VerticalAlignment="Center"
+                                FontWeight="Normal"
+                                Text="{Binding SweepStep, StringFormat='{}{0:F2} g'}" />
+                        </StackPanel>
                     </StackPanel>
                 </Expander>
             </StackPanel>

+ 4 - 145
Avalonia/ShakerApp/Views/ShakerStatusControl/ShakerStatusControlView.axaml

@@ -6,6 +6,7 @@
     xmlns:local="using:ShakerApp"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     xmlns:oxy="http://oxyplot.org/avalonia"
+    xmlns:view="using:ShakerApp.Views"
     xmlns:vm="using:ShakerApp.ViewModels"
     d:DesignHeight="450"
     d:DesignWidth="800"
@@ -24,150 +25,8 @@
                 <ColumnDefinition MinWidth="600" />
             </Grid.ColumnDefinitions>
             <GridSplitter Grid.Column="1" />
-            <oxy:PlotView
-                Background="Transparent"
-                Controller="{Binding DisplacementController}"
-                Model="{Binding DisplacementModel}" />
-            <StackPanel
-                HorizontalAlignment="Right"
-                VerticalAlignment="Top"
-                Orientation="Horizontal">
-                <TextBlock VerticalAlignment="Center" Text="{DynamicResource Statistics}" />
-                <ToggleSwitch IsChecked="{Binding DisplacementStatisticsVisibily, Mode=TwoWay}" />
-            </StackPanel>
-            <Border
-                Margin="80,60"
-                HorizontalAlignment="Left"
-                VerticalAlignment="Top"
-                Background="#1FAAAAAA"
-                CornerRadius="6"
-                IsHitTestVisible="False"
-                IsVisible="{Binding DisplacementStatisticsVisibily}">
-                <StackPanel Margin="10">
-                    <Grid Height="20" ColumnDefinitions="80,80,80,80">
-                        <TextBlock
-                            HorizontalAlignment="Center"
-                            VerticalAlignment="Center"
-                            Text="{DynamicResource ChannelName}" />
-                        <TextBlock
-                            Grid.Column="1"
-                            HorizontalAlignment="Center"
-                            VerticalAlignment="Center"
-                            Text="{DynamicResource Max}" />
-                        <TextBlock
-                            Grid.Column="2"
-                            HorizontalAlignment="Center"
-                            VerticalAlignment="Center"
-                            Text="{DynamicResource Min}" />
-                        <TextBlock
-                            Grid.Column="3"
-                            HorizontalAlignment="Center"
-                            VerticalAlignment="Center"
-                            Text="{DynamicResource Rms}" />
-                    </Grid>
-                    <ItemsControl ItemsSource="{Binding DisplacementStatistics}">
-                        <ItemsControl.ItemTemplate>
-                            <DataTemplate>
-                                <Grid Height="20" ColumnDefinitions="80,80,80,80">
-                                    <TextBlock
-                                        HorizontalAlignment="Center"
-                                        VerticalAlignment="Center"
-                                        Text="{local:ResourceBinding Name}" />
-                                    <TextBlock
-                                        Grid.Column="1"
-                                        HorizontalAlignment="Center"
-                                        VerticalAlignment="Center"
-                                        Text="{Binding Max, StringFormat='{}{0:F3}'}" />
-                                    <TextBlock
-                                        Grid.Column="2"
-                                        HorizontalAlignment="Center"
-                                        VerticalAlignment="Center"
-                                        Text="{Binding Min, StringFormat='{}{0:F3}'}" />
-                                    <TextBlock
-                                        Grid.Column="3"
-                                        HorizontalAlignment="Center"
-                                        VerticalAlignment="Center"
-                                        Text="{Binding RMS, StringFormat='{}{0:F3}'}" />
-                                </Grid>
-                            </DataTemplate>
-                        </ItemsControl.ItemTemplate>
-                    </ItemsControl>
-                </StackPanel>
-            </Border>
-            <oxy:PlotView
-                Grid.Column="2"
-                Background="Transparent"
-                Controller="{Binding ServoValveController}"
-                Model="{Binding ServoValveModel}" />
-            <StackPanel
-                Grid.Column="2"
-                HorizontalAlignment="Right"
-                VerticalAlignment="Top"
-                Orientation="Horizontal">
-                <TextBlock VerticalAlignment="Center" Text="{DynamicResource Statistics}" />
-                <ToggleSwitch IsChecked="{Binding ServoValveStatisticsVisibily, Mode=TwoWay}" />
-            </StackPanel>
-            <Border
-                Grid.Column="2"
-                Margin="80,60"
-                HorizontalAlignment="Left"
-                VerticalAlignment="Top"
-                Background="#1FAAAAAA"
-                CornerRadius="6"
-                IsHitTestVisible="False"
-                IsVisible="{Binding ServoValveStatisticsVisibily}">
-                <StackPanel Margin="10">
-                    <Grid Height="20" ColumnDefinitions="80,80,80,80">
-                        <TextBlock
-                            HorizontalAlignment="Center"
-                            VerticalAlignment="Center"
-                            Text="{DynamicResource ChannelName}" />
-                        <TextBlock
-                            Grid.Column="1"
-                            HorizontalAlignment="Center"
-                            VerticalAlignment="Center"
-                            Text="{DynamicResource Max}" />
-                        <TextBlock
-                            Grid.Column="2"
-                            HorizontalAlignment="Center"
-                            VerticalAlignment="Center"
-                            Text="{DynamicResource Min}" />
-                        <TextBlock
-                            Grid.Column="3"
-                            HorizontalAlignment="Center"
-                            VerticalAlignment="Center"
-                            Text="{DynamicResource Rms}" />
-                    </Grid>
-                    <ItemsControl ItemsSource="{Binding ServoValveStatistics}">
-                        <ItemsControl.ItemTemplate>
-                            <DataTemplate>
-                                <Grid Height="20" ColumnDefinitions="80,80,80,80">
-                                    <TextBlock
-                                        HorizontalAlignment="Center"
-                                        VerticalAlignment="Center"
-                                        Text="{local:ResourceBinding Name}" />
-                                    <TextBlock
-                                        Grid.Column="1"
-                                        HorizontalAlignment="Center"
-                                        VerticalAlignment="Center"
-                                        Text="{Binding Max, StringFormat='{}{0:F3}'}" />
-                                    <TextBlock
-                                        Grid.Column="2"
-                                        HorizontalAlignment="Center"
-                                        VerticalAlignment="Center"
-                                        Text="{Binding Min, StringFormat='{}{0:F3}'}" />
-                                    <TextBlock
-                                        Grid.Column="3"
-                                        HorizontalAlignment="Center"
-                                        VerticalAlignment="Center"
-                                        Text="{Binding RMS, StringFormat='{}{0:F3}'}" />
-                                </Grid>
-                            </DataTemplate>
-                        </ItemsControl.ItemTemplate>
-                    </ItemsControl>
-                </StackPanel>
-
-            </Border>
+            <view:AnalogSignalPreviewView DataContext="{Binding DisplacementSignal}" />
+            <view:AnalogSignalPreviewView Grid.Column="2" DataContext="{Binding ValveDriveSignal}" />
         </Grid>
         <StackPanel Grid.Column="1">
             <StackPanel Margin="0,10,10,0">
@@ -212,7 +71,7 @@
                 Height="{StaticResource ControlButtonHeight}"
                 Margin="0,10,10,0"
                 Command="{Binding ResetCommand}"
-                IsEnabled="{Binding RiseTableEnabled}">
+                IsEnabled="{Binding RestEnabeld}">
                 <StackPanel Orientation="Horizontal">
                     <PathIcon Data="{StaticResource ResetGeometry}" />
                     <TextBlock Text="{DynamicResource Reset}" />

+ 103 - 0
Avalonia/ShakerApp/Views/SignalPreview/AnalogSignalPreviewView.axaml

@@ -0,0 +1,103 @@
+<UserControl
+    x:Class="ShakerApp.Views.AnalogSignalPreviewView"
+    xmlns="https://github.com/avaloniaui"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+    xmlns:local="using:ShakerApp"
+    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+    xmlns:oxy="http://oxyplot.org/avalonia"
+    xmlns:vm="using:ShakerApp.ViewModels"
+    d:DesignHeight="450"
+    d:DesignWidth="800"
+    x:DataType="vm:AnalogSignalPreviewViewModel"
+    mc:Ignorable="d">
+    <Grid>
+        <oxy:PlotView
+            Background="Transparent"
+            Controller="{Binding PlotController}"
+            Model="{Binding PlotModel}" />
+        <StackPanel
+            HorizontalAlignment="Right"
+            VerticalAlignment="Top"
+            Orientation="Horizontal">
+            <StackPanel IsVisible="{Binding CanChangedAnalog}" Orientation="Horizontal">
+                <TextBlock VerticalAlignment="Center" Text="信号" />
+                <ComboBox
+                    Width="120"
+                    ItemsSource="{Binding AllAnalogTypes}"
+                    SelectedValue="{Binding Path=Value}"
+                    SelectedValueBinding="{Binding Value}">
+                    <ComboBox.ItemTemplate>
+                        <DataTemplate>
+                            <TextBlock Text="{local:ResourceBinding Key}" />
+                        </DataTemplate>
+                    </ComboBox.ItemTemplate>
+
+                </ComboBox>
+            </StackPanel>
+            <StackPanel Margin="10,0,0,0" Orientation="Horizontal">
+                <TextBlock VerticalAlignment="Center" Text="{DynamicResource Statistics}" />
+                <ToggleSwitch IsChecked="{Binding StatisticsVisibily, Mode=TwoWay}" />
+            </StackPanel>
+        </StackPanel>
+        <Border
+            Margin="80,60"
+            HorizontalAlignment="Left"
+            VerticalAlignment="Top"
+            Background="#1FAAAAAA"
+            CornerRadius="6"
+            IsHitTestVisible="False"
+            IsVisible="{Binding StatisticsVisibily}">
+            <StackPanel Margin="10">
+                <Grid Height="20" ColumnDefinitions="80,80,80,80">
+                    <TextBlock
+                        HorizontalAlignment="Center"
+                        VerticalAlignment="Center"
+                        Text="{DynamicResource ChannelName}" />
+                    <TextBlock
+                        Grid.Column="1"
+                        HorizontalAlignment="Center"
+                        VerticalAlignment="Center"
+                        Text="{DynamicResource Max}" />
+                    <TextBlock
+                        Grid.Column="2"
+                        HorizontalAlignment="Center"
+                        VerticalAlignment="Center"
+                        Text="{DynamicResource Min}" />
+                    <TextBlock
+                        Grid.Column="3"
+                        HorizontalAlignment="Center"
+                        VerticalAlignment="Center"
+                        Text="{DynamicResource Rms}" />
+                </Grid>
+                <ItemsControl ItemsSource="{Binding Statistics}">
+                    <ItemsControl.ItemTemplate>
+                        <DataTemplate>
+                            <Grid Height="20" ColumnDefinitions="80,80,80,80">
+                                <TextBlock
+                                    HorizontalAlignment="Center"
+                                    VerticalAlignment="Center"
+                                    Text="{local:ResourceBinding Name}" />
+                                <TextBlock
+                                    Grid.Column="1"
+                                    HorizontalAlignment="Center"
+                                    VerticalAlignment="Center"
+                                    Text="{Binding Max, StringFormat='{}{0:F3}'}" />
+                                <TextBlock
+                                    Grid.Column="2"
+                                    HorizontalAlignment="Center"
+                                    VerticalAlignment="Center"
+                                    Text="{Binding Min, StringFormat='{}{0:F3}'}" />
+                                <TextBlock
+                                    Grid.Column="3"
+                                    HorizontalAlignment="Center"
+                                    VerticalAlignment="Center"
+                                    Text="{Binding RMS, StringFormat='{}{0:F3}'}" />
+                            </Grid>
+                        </DataTemplate>
+                    </ItemsControl.ItemTemplate>
+                </ItemsControl>
+            </StackPanel>
+        </Border>
+    </Grid>
+</UserControl>

+ 13 - 0
Avalonia/ShakerApp/Views/SignalPreview/AnalogSignalPreviewView.axaml.cs

@@ -0,0 +1,13 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace ShakerApp.Views;
+
+public partial class AnalogSignalPreviewView : UserControl
+{
+    public AnalogSignalPreviewView()
+    {
+        InitializeComponent();
+    }
+}

+ 11 - 7
Avalonia/ShakerApp/Views/SignalPreview/SignalPreviewView.axaml

@@ -1,8 +1,12 @@
-<UserControl xmlns="https://github.com/avaloniaui"
-             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
-             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
-             mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
-             x:Class="ShakerApp.Views.SignalPreviewView">
-  Welcome to Avalonia!
+<UserControl
+    x:Class="ShakerApp.Views.SignalPreviewView"
+    xmlns="https://github.com/avaloniaui"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+    xmlns:oxy="http://oxyplot.org/avalonia"
+    d:DesignHeight="450"
+    d:DesignWidth="800"
+    mc:Ignorable="d">
+    aaa
 </UserControl>

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

@@ -31,7 +31,8 @@ namespace FxpConvert.Common
         /// </summary>
         public IArraySum Sum { get; }
         public void Fill(ref float result, float value, uint count);
-        
+        public void Fill(ref double result, double value, uint count);
+
     }
 
     public interface IArraySum
@@ -52,6 +53,12 @@ namespace FxpConvert.Common
         public void Add(ref float left, ref float right, uint count, ref float result);
         public void Add(ref float left, float right, uint count);
         public void Add(ref float left, ref float right, uint count);
+
+
+        public void Add(ref double left, double right, uint count, ref double result);
+        public void Add(ref double left, ref double right, uint count, ref double result);
+        public void Add(ref double left, double right, uint count);
+        public void Add(ref double left, ref double right, uint count);
     }
     public interface ISubtract
     {
@@ -59,6 +66,11 @@ namespace FxpConvert.Common
         public void Subtract(ref float left, ref float right, uint count, ref float result);
         public void Subtract(ref float left, float right, uint count);
         public void Subtract(ref float left, ref float right, uint count);
+
+        public void Subtract(ref double left, double right, uint count, ref double result);
+        public void Subtract(ref double left, ref double right, uint count, ref double result);
+        public void Subtract(ref double left, double right, uint count);
+        public void Subtract(ref double left, ref double right, uint count);
     }
 
     public interface IMultiply
@@ -67,6 +79,11 @@ namespace FxpConvert.Common
         public void Multiply(ref float left, ref float right, uint count, ref float result);
         public void Multiply(ref float left, float right, uint count);
         public void Multiply(ref float left, ref float right, uint count);
+
+        public void Multiply(ref double left, double right, uint count, ref double result);
+        public void Multiply(ref double left, ref double right, uint count, ref double result);
+        public void Multiply(ref double left, double right, uint count);
+        public void Multiply(ref double left, ref double right, uint count);
     }
 
     public interface IDivision
@@ -75,5 +92,10 @@ namespace FxpConvert.Common
         public void Division(ref float left, ref float right, uint count, ref float result);
         public void Division(ref float left, float right, uint count);
         public void Division(ref float left, ref float right, uint count);
+
+        public void Division(ref double left, double right, uint count, ref double result);
+        public void Division(ref double left, ref double right, uint count, ref double result);
+        public void Division(ref double left, double right, uint count);
+        public void Division(ref double left, ref double right, uint count);
     }
 }

+ 437 - 0
Calc/SIMDFxpConvert/SIMDCalc.cs

@@ -32,6 +32,15 @@ namespace SIMDFxpConvert
                 ptr[i] = value;
             }
         }
+        public unsafe void Fill(ref double result, double value, uint count)
+        {
+            if (count == 0) return;
+            double* ptr = (double*)Unsafe.AsPointer(ref result);
+            for (int i = 0; i < count; i++)
+            {
+                ptr[i] = value;
+            }
+        }
     }
     public sealed class SIMDArraySum : IArraySum
     {
@@ -241,6 +250,116 @@ namespace SIMDFxpConvert
                 }
             }
         }
+
+
+
+
+
+        public void Add(ref double left, double right, uint count, ref double result)
+        {
+            if (count == 0) return;
+            ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
+            ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
+            uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
+            uint c = count / onecount;
+            uint c1 = count % onecount;
+            uint start = c * onecount;
+            var rightarray = Enumerable.Repeat(right, (int)onecount).ToArray();
+            ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref rightarray[0]);
+            for (int i = 0; i < c; i++)
+            {
+                ref var tempdesc = ref Unsafe.Add(ref desc, i);
+                tempdesc = Unsafe.Add(ref source, i) + tempright;
+            }
+            if (c1 > 0)
+            {
+                double* leftptr = (double*)Unsafe.AsPointer(ref left);
+                double* resultptr = (double*)Unsafe.AsPointer(ref result);
+                for (int i = 0; i < c1; i++)
+                {
+                    resultptr[start + i] = leftptr[start + i] + right;
+                }
+
+            }
+        }
+
+        public void Add(ref double left, ref double right, uint count, ref double result)
+        {
+            if (count == 0) return;
+            ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
+            ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
+            uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
+            uint c = count / onecount;
+            uint c1 = count % onecount;
+            uint start = c * onecount;
+            ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
+            for (int i = 0; i < c; i++)
+            {
+                ref var tempdesc = ref Unsafe.Add(ref desc, i);
+                tempdesc = Unsafe.Add(ref source, i) + Unsafe.Add(ref tempright, i);
+            }
+            if (c1 > 0)
+            {
+                double* leftptr = (double*)Unsafe.AsPointer(ref left);
+                double* resultptr = (double*)Unsafe.AsPointer(ref result);
+                double* rightptr = (double*)Unsafe.AsPointer(ref right);
+                for (int i = 0; i < c1; i++)
+                {
+                    resultptr[start + i] = leftptr[start + i] + rightptr[start + i];
+                }
+
+            }
+        }
+
+        public void Add(ref double left, double right, uint count)
+        {
+            if (count == 0) return;
+            ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
+            uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
+            uint c = count / onecount;
+            uint c1 = count % onecount;
+            uint start = c * onecount;
+            var rightarray = Enumerable.Repeat(right, (int)onecount).ToArray();
+            ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref rightarray[0]);
+            for (int i = 0; i < c; i++)
+            {
+                ref var tempdesc = ref Unsafe.Add(ref source, i);
+                tempdesc += tempright;
+            }
+            if (c1 > 0)
+            {
+                double* leftptr = (double*)Unsafe.AsPointer(ref left);
+                for (int i = 0; i < c1; i++)
+                {
+                    leftptr[start + i] += right;
+                }
+            }
+        }
+
+        public void Add(ref double left, ref double right, uint count)
+        {
+            if (count == 0) return;
+            ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
+            uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
+            uint c = count / onecount;
+            uint c1 = count % onecount;
+            uint start = c * onecount;
+            ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
+            for (int i = 0; i < c; i++)
+            {
+                ref var tempdesc = ref Unsafe.Add(ref source, i);
+                tempdesc += Unsafe.Add(ref tempright, i);
+            }
+            if (c1 > 0)
+            {
+                double* leftptr = (double*)Unsafe.AsPointer(ref left);
+                double* rightptr = (double*)Unsafe.AsPointer(ref right);
+                for (int i = 0; i < c1; i++)
+                {
+                    leftptr[start + i] += rightptr[start + i];
+                }
+            }
+        }
     }
     public unsafe sealed class SIMDSubtract : ISubtract
     {
@@ -349,6 +468,115 @@ namespace SIMDFxpConvert
                 }
             }
         }
+
+
+
+
+        public void Subtract(ref double left, double right, uint count, ref double result)
+        {
+            if (count == 0) return;
+            ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
+            ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
+            uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
+            uint c = count / onecount;
+            uint c1 = count % onecount;
+            uint start = c * onecount;
+            var rightarray = Enumerable.Repeat(right, (int)onecount).ToArray();
+            ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref rightarray[0]);
+            for (int i = 0; i < c; i++)
+            {
+                ref var tempdesc = ref Unsafe.Add(ref desc, i);
+                tempdesc = Unsafe.Add(ref source, i) - tempright;
+            }
+            if (c1 > 0)
+            {
+                double* leftptr = (double*)Unsafe.AsPointer(ref left);
+                double* resultptr = (double*)Unsafe.AsPointer(ref result);
+                for (int i = 0; i < c1; i++)
+                {
+                    resultptr[start + i] = leftptr[start + i] - right;
+                }
+
+            }
+        }
+
+        public void Subtract(ref double left, ref double right, uint count, ref double result)
+        {
+            if (count == 0) return;
+            ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
+            ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
+            uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
+            uint c = count / onecount;
+            uint c1 = count % onecount;
+            uint start = c * onecount;
+            ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
+            for (int i = 0; i < c; i++)
+            {
+                ref var tempdesc = ref Unsafe.Add(ref desc, i);
+                tempdesc = Unsafe.Add(ref source, i) - Unsafe.Add(ref tempright, i);
+            }
+            if (c1 > 0)
+            {
+                double* leftptr = (double*)Unsafe.AsPointer(ref left);
+                double* resultptr = (double*)Unsafe.AsPointer(ref result);
+                double* rightptr = (double*)Unsafe.AsPointer(ref right);
+                for (int i = 0; i < c1; i++)
+                {
+                    resultptr[start + i] = leftptr[start + i] - rightptr[start + i];
+                }
+
+            }
+        }
+
+        public void Subtract(ref double left, double right, uint count)
+        {
+            if (count == 0) return;
+            ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
+            uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
+            uint c = count / onecount;
+            uint c1 = count % onecount;
+            uint start = c * onecount;
+            var rightarray = Enumerable.Repeat(right, (int)onecount).ToArray();
+            ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref rightarray[0]);
+            for (int i = 0; i < c; i++)
+            {
+                ref var tempdesc = ref Unsafe.Add(ref source, i);
+                tempdesc -= tempright;
+            }
+            if (c1 > 0)
+            {
+                double* leftptr = (double*)Unsafe.AsPointer(ref left);
+                for (int i = 0; i < c1; i++)
+                {
+                    leftptr[start + i] -= right;
+                }
+            }
+        }
+
+        public void Subtract(ref double left, ref double right, uint count)
+        {
+            if (count == 0) return;
+            ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
+            uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
+            uint c = count / onecount;
+            uint c1 = count % onecount;
+            uint start = c * onecount;
+            ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
+            for (int i = 0; i < c; i++)
+            {
+                ref var tempdesc = ref Unsafe.Add(ref source, i);
+                tempdesc -= Unsafe.Add(ref tempright, i);
+            }
+            if (c1 > 0)
+            {
+                double* leftptr = (double*)Unsafe.AsPointer(ref left);
+                double* rightptr = (double*)Unsafe.AsPointer(ref right);
+                for (int i = 0; i < c1; i++)
+                {
+                    leftptr[start + i] -= rightptr[start + i];
+                }
+            }
+        }
     }
 
     public unsafe sealed class SIMDMultiply : IMultiply
@@ -454,6 +682,112 @@ namespace SIMDFxpConvert
                 }
             }
         }
+
+
+
+
+
+        public void Multiply(ref double left, double right, uint count, ref double result)
+        {
+            if (count == 0) return;
+            ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
+            ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
+            uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
+            uint c = count / onecount;
+            uint c1 = count % onecount;
+            uint start = c * onecount;
+            for (int i = 0; i < c; i++)
+            {
+                ref var tempdesc = ref Unsafe.Add(ref desc, i);
+                tempdesc = Unsafe.Add(ref source, i) * right;
+            }
+            if (c1 > 0)
+            {
+                double* leftptr = (double*)Unsafe.AsPointer(ref left);
+                double* resultptr = (double*)Unsafe.AsPointer(ref result);
+                for (int i = 0; i < c1; i++)
+                {
+                    resultptr[start + i] = leftptr[start + i] * right;
+                }
+
+            }
+        }
+
+        public void Multiply(ref double left, ref double right, uint count, ref double result)
+        {
+            if (count == 0) return;
+            ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
+            ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
+            uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
+            uint c = count / onecount;
+            uint c1 = count % onecount;
+            uint start = c * onecount;
+            ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
+            for (int i = 0; i < c; i++)
+            {
+                ref var tempdesc = ref Unsafe.Add(ref desc, i);
+                tempdesc = Unsafe.Add(ref source, i) * Unsafe.Add(ref tempright, i);
+            }
+            if (c1 > 0)
+            {
+                double* leftptr = (double*)Unsafe.AsPointer(ref left);
+                double* resultptr = (double*)Unsafe.AsPointer(ref result);
+                double* rightptr = (double*)Unsafe.AsPointer(ref right);
+                for (int i = 0; i < c1; i++)
+                {
+                    resultptr[start + i] = leftptr[start + i] * rightptr[start + i];
+                }
+
+            }
+        }
+
+        public void Multiply(ref double left, double right, uint count)
+        {
+            if (count == 0) return;
+            ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
+            uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
+            uint c = count / onecount;
+            uint c1 = count % onecount;
+            uint start = c * onecount;
+            for (int i = 0; i < c; i++)
+            {
+                ref var tempdesc = ref Unsafe.Add(ref source, i);
+                tempdesc *= right;
+            }
+            if (c1 > 0)
+            {
+                double* leftptr = (double*)Unsafe.AsPointer(ref left);
+                for (int i = 0; i < c1; i++)
+                {
+                    leftptr[start + i] *= right;
+                }
+            }
+        }
+
+        public void Multiply(ref double left, ref double right, uint count)
+        {
+            if (count == 0) return;
+            ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
+            uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
+            uint c = count / onecount;
+            uint c1 = count % onecount;
+            uint start = c * onecount;
+            ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
+            for (int i = 0; i < c; i++)
+            {
+                ref var tempdesc = ref Unsafe.Add(ref source, i);
+                tempdesc *= Unsafe.Add(ref tempright, i);
+            }
+            if (c1 > 0)
+            {
+                double* leftptr = (double*)Unsafe.AsPointer(ref left);
+                double* rightptr = (double*)Unsafe.AsPointer(ref right);
+                for (int i = 0; i < c1; i++)
+                {
+                    leftptr[start + i] *= rightptr[start + i];
+                }
+            }
+        }
     }
     public unsafe sealed class SIMDDivision : IDivision
     {
@@ -558,5 +892,108 @@ namespace SIMDFxpConvert
                 }
             }
         }
+
+
+        public void Division(ref double left, double right, uint count, ref double result)
+        {
+            if (count == 0) return;
+            ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
+            ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
+            uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
+            uint c = count / onecount;
+            uint c1 = count % onecount;
+            uint start = c * onecount;
+            for (int i = 0; i < c; i++)
+            {
+                ref var tempdesc = ref Unsafe.Add(ref desc, i);
+                tempdesc = Unsafe.Add(ref source, i) / right;
+            }
+            if (c1 > 0)
+            {
+                double* leftptr = (double*)Unsafe.AsPointer(ref left);
+                double* resultptr = (double*)Unsafe.AsPointer(ref result);
+                for (int i = 0; i < c1; i++)
+                {
+                    resultptr[start + i] = leftptr[start + i] / right;
+                }
+
+            }
+        }
+
+        public void Division(ref double left, ref double right, uint count, ref double result)
+        {
+            if (count == 0) return;
+            ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
+            ref var desc = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref result);
+            uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
+            uint c = count / onecount;
+            uint c1 = count % onecount;
+            uint start = c * onecount;
+            ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
+            for (int i = 0; i < c; i++)
+            {
+                ref var tempdesc = ref Unsafe.Add(ref desc, i);
+                tempdesc = Unsafe.Add(ref source, i) / Unsafe.Add(ref tempright, i);
+            }
+            if (c1 > 0)
+            {
+                double* leftptr = (double*)Unsafe.AsPointer(ref left);
+                double* resultptr = (double*)Unsafe.AsPointer(ref result);
+                double* rightptr = (double*)Unsafe.AsPointer(ref right);
+                for (int i = 0; i < c1; i++)
+                {
+                    resultptr[start + i] = leftptr[start + i] / rightptr[start + i];
+                }
+
+            }
+        }
+
+        public void Division(ref double left, double right, uint count)
+        {
+            if (count == 0) return;
+            ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
+            uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
+            uint c = count / onecount;
+            uint c1 = count % onecount;
+            uint start = c * onecount;
+            for (int i = 0; i < c; i++)
+            {
+                ref var tempdesc = ref Unsafe.Add(ref source, i);
+                tempdesc /= right;
+            }
+            if (c1 > 0)
+            {
+                double* leftptr = (double*)Unsafe.AsPointer(ref left);
+                for (int i = 0; i < c1; i++)
+                {
+                    leftptr[start + i] /= right;
+                }
+            }
+        }
+
+        public void Division(ref double left, ref double right, uint count)
+        {
+            if (count == 0) return;
+            ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref left);
+            uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
+            uint c = count / onecount;
+            uint c1 = count % onecount;
+            uint start = c * onecount;
+            ref var tempright = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref right);
+            for (int i = 0; i < c; i++)
+            {
+                ref var tempdesc = ref Unsafe.Add(ref source, i);
+                tempdesc /= Unsafe.Add(ref tempright, i);
+            }
+            if (c1 > 0)
+            {
+                double* leftptr = (double*)Unsafe.AsPointer(ref left);
+                double* rightptr = (double*)Unsafe.AsPointer(ref right);
+                for (int i = 0; i < c1; i++)
+                {
+                    leftptr[start + i] /= rightptr[start + i];
+                }
+            }
+        }
     }
 }

+ 2 - 2
Calc/SIMDFxpConvert/SIMDFxpConverter.cs

@@ -76,7 +76,7 @@ namespace SIMDFxpConvert
         {
             if (count == 0) return;
             double delta = Math.Pow(2, dxpinfo.integerWordLength - dxpinfo.wordLength);
-            ulong mask = (1ul << dxpinfo.wordLength) - 1;
+            ulong mask = dxpinfo.wordLength == 64 ? ulong.MaxValue : ((1ul << dxpinfo.wordLength) - 1);
             if (dxpinfo.isSigned)
             {
                 ulong signedmask = 1ul << (dxpinfo.wordLength - 1);
@@ -110,7 +110,7 @@ namespace SIMDFxpConvert
         {
             if (count == 0) return;
             float delta = MathF.Pow(2, dxpinfo.integerWordLength - dxpinfo.wordLength);
-            ulong mask = (1ul << dxpinfo.wordLength) - 1;
+            ulong mask = dxpinfo.wordLength == 64 ? ulong.MaxValue : ((1ul << dxpinfo.wordLength) - 1);
             if (dxpinfo.isSigned)
             {
                 ulong signedmask = 1ul << (dxpinfo.wordLength - 1);

+ 2 - 2
Communication/NetMQ/Core/Mailbox.cs

@@ -159,7 +159,7 @@ namespace NetMQ.Core
 
             bool ok = m_commandPipe.TryRead(out Command cmd);
 
-            Debug.Assert(!ok);
+            //Debug.Assert(!ok);
 
             m_active = false;
 
@@ -234,7 +234,7 @@ namespace NetMQ.Core
 
             // Get a command.
             var ok = m_commandPipe.TryRead(out command);
-            Debug.Assert(ok);
+           // Debug.Assert(ok);
             return ok;
         }
 

+ 1 - 1
Communication/TcpEventBus/ISocket.cs

@@ -26,7 +26,7 @@ namespace TcpEventBus
         {
             public static ISocket CreateService(int port, int timeout = 1000)
             {
-                return new Server("*", port)
+                return new Server("0.0.0.0", port)
                 {
                 };
             }

+ 32 - 0
Communication/TcpEventBus/Server.cs

@@ -46,6 +46,14 @@ namespace TcpEventBus
 
         public void Disconnect()
         {
+            if (System.Console.IsOutputRedirected)
+            {
+                System.Diagnostics.Debug.WriteLine($"{DateTime.Now}:{nameof(Disconnect)}");
+            }
+            else
+            {
+                Console.WriteLine($"{DateTime.Now}:{nameof(Disconnect)}");
+            }
             poller.Stop();
             IsConnect = false;
         }
@@ -58,6 +66,14 @@ namespace TcpEventBus
 
         public void Start()
         {
+            if (System.Console.IsOutputRedirected)
+            {
+                System.Diagnostics.Debug.WriteLine($"{DateTime.Now}:{nameof(Start)}");
+            }
+            else
+            {
+                Console.WriteLine($"{DateTime.Now}:{nameof(Start)}");
+            }
             Task.Run(() => poller.Run());
             IsConnect = true;
         }
@@ -106,6 +122,14 @@ namespace TcpEventBus
 
         public void Disconnect()
         {
+            if (System.Console.IsOutputRedirected)
+            {
+                System.Diagnostics.Debug.WriteLine($"{DateTime.Now}:{nameof(Disconnect)}");
+            }
+            else
+            {
+                Console.WriteLine($"{DateTime.Now}:{nameof(Disconnect)}");
+            }
             _server.Disconnect(ServerAddress);
             _client.Disconnect(ClientAddress);
             _poller.Stop();
@@ -123,6 +147,14 @@ namespace TcpEventBus
             _client.Connect(ClientAddress);
             _server.Connect(ServerAddress);
             Thread.Sleep(100);
+            if (System.Console.IsOutputRedirected)
+            {
+                System.Diagnostics.Debug.WriteLine($"{DateTime.Now}:{nameof(Start)}");
+            }
+            else
+            {
+                Console.WriteLine($"{DateTime.Now}:{nameof(Start)}");
+            }
             Task.Run(() => _poller.Run());
             IsConnect = true;
         }

+ 0 - 8
Communication/TcpEventBus/TcpEventBus.cs

@@ -45,14 +45,6 @@ namespace TcpEventBus
             try
             {
                 var msg = MessagePack.MessagePackSerializer.Deserialize<DataMsg>(e);
-                if(msg == null)
-                {
-                    Console.WriteLine($"{DateTime.Now}:msg is null");
-                }
-                else
-                {
-                    Console.WriteLine($"{DateTime.Now}:{msg.EventType}");
-                }
                 if (msg == null) return;
                 if(_list.TryGetValue(msg.EventType,out var baseevent))
                 {

+ 1 - 0
Language/Zh-CN/Language.axaml

@@ -142,6 +142,7 @@
     <s:String x:Key="Synthesis">合成</s:String>
     <s:String x:Key="ChannelName">通道名</s:String>
 
+
     <s:String x:Key="Start">启动</s:String>
     <s:String x:Key="Stop">停止</s:String>
     <s:String x:Key="InputPassWord">输入密码</s:String>

+ 146 - 26
NIFPGA/FPGA.cs

@@ -168,12 +168,13 @@ namespace NIFPGA
                 switch (reg.Datatype)
                 {
                     case lvbitx.Datatype.Int16:
-                        if(!reg.Indicator)
+                        if (!reg.Indicator)
                         {
 
                             properties.Add(new FPGAWriteProperty<short>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         else
@@ -181,6 +182,7 @@ namespace NIFPGA
                             properties.Add(new FPGAReadProperty<short>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         break;
@@ -191,6 +193,7 @@ namespace NIFPGA
                             properties.Add(new FPGAWriteProperty<bool>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         else
@@ -198,6 +201,7 @@ namespace NIFPGA
                             properties.Add(new FPGAReadProperty<bool>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         break;
@@ -208,6 +212,7 @@ namespace NIFPGA
                             properties.Add(new FPGAWriteProperty<sbyte>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         else
@@ -215,6 +220,7 @@ namespace NIFPGA
                             properties.Add(new FPGAReadProperty<sbyte>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         break;
@@ -225,6 +231,7 @@ namespace NIFPGA
                             properties.Add(new FPGAWriteProperty<byte>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         else
@@ -232,6 +239,7 @@ namespace NIFPGA
                             properties.Add(new FPGAReadProperty<byte>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         break;
@@ -242,6 +250,7 @@ namespace NIFPGA
                             properties.Add(new FPGAWriteProperty<ushort>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         else
@@ -249,6 +258,7 @@ namespace NIFPGA
                             properties.Add(new FPGAReadProperty<ushort>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         break;
@@ -259,6 +269,7 @@ namespace NIFPGA
                             properties.Add(new FPGAWriteProperty<int>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         else
@@ -266,6 +277,7 @@ namespace NIFPGA
                             properties.Add(new FPGAReadProperty<int>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         break;
@@ -276,6 +288,7 @@ namespace NIFPGA
                             properties.Add(new FPGAWriteProperty<uint>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         else
@@ -283,6 +296,7 @@ namespace NIFPGA
                             properties.Add(new FPGAReadProperty<uint>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         break;
@@ -293,6 +307,7 @@ namespace NIFPGA
                             properties.Add(new FPGAWriteProperty<long>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         else
@@ -300,6 +315,7 @@ namespace NIFPGA
                             properties.Add(new FPGAReadProperty<long>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         break;
@@ -310,6 +326,7 @@ namespace NIFPGA
                             properties.Add(new FPGAWriteProperty<ulong>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         else
@@ -317,6 +334,7 @@ namespace NIFPGA
                             properties.Add(new FPGAReadProperty<ulong>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         break;
@@ -327,6 +345,7 @@ namespace NIFPGA
                             properties.Add(new FPGAWriteProperty<float>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         else
@@ -334,6 +353,7 @@ namespace NIFPGA
                             properties.Add(new FPGAReadProperty<float>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         break;
@@ -344,6 +364,7 @@ namespace NIFPGA
                             properties.Add(new FPGAWriteProperty<double>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         else
@@ -351,6 +372,7 @@ namespace NIFPGA
                             properties.Add(new FPGAReadProperty<double>(session, reg.Offset)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         break;
@@ -360,6 +382,7 @@ namespace NIFPGA
                             properties.Add(new FPGAFXPWriteProperty(session, reg.Offset, reg.FxpTypeInfo, _FXPConvert)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         else
@@ -367,6 +390,7 @@ namespace NIFPGA
                             properties.Add(new FPGAFXPReadProperty(session, reg.Offset, reg.FxpTypeInfo, _FXPConvert)
                             {
                                 Name = reg.Name,
+                                SizeInBits = reg.SizeInBits,
                             });
                         }
                         break;
@@ -374,123 +398,219 @@ namespace NIFPGA
                         switch (reg.ArrayValueType)
                         {
                             case lvbitx.Datatype.Boolean:
-                                if(!reg.Indicator)
+                                if (!reg.Indicator)
                                 {
-                                    properties.Add(new FPGAArrayWriteProperty<bool>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayWriteProperty<bool>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 else
                                 {
-                                    properties.Add(new FPGAArrayReadProperty<bool>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayReadProperty<bool>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 break;
                             case lvbitx.Datatype.Int8:
                                 if (!reg.Indicator)
                                 {
-                                    properties.Add(new FPGAArrayWriteProperty<sbyte>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayWriteProperty<sbyte>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 else
                                 {
-                                    properties.Add(new FPGAArrayReadProperty<sbyte>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayReadProperty<sbyte>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 break;
                             case lvbitx.Datatype.Uint8:
                                 if (!reg.Indicator)
                                 {
-                                    properties.Add(new FPGAArrayWriteProperty<byte>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayWriteProperty<byte>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 else
                                 {
-                                    properties.Add(new FPGAArrayReadProperty<byte>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayReadProperty<byte>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 break;
                             case lvbitx.Datatype.Int16:
                                 if (!reg.Indicator)
                                 {
-                                    properties.Add(new FPGAArrayWriteProperty<short>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayWriteProperty<short>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 else
                                 {
-                                    properties.Add(new FPGAArrayReadProperty<short>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayReadProperty<short>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 break;
                             case lvbitx.Datatype.Uint16:
                                 if (!reg.Indicator)
                                 {
-                                    properties.Add(new FPGAArrayWriteProperty<ushort>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayWriteProperty<ushort>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 else
                                 {
-                                    properties.Add(new FPGAArrayReadProperty<ushort>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayReadProperty<ushort>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 break;
                             case lvbitx.Datatype.Int32:
                                 if (!reg.Indicator)
                                 {
-                                    properties.Add(new FPGAArrayWriteProperty<int>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayWriteProperty<int>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 else
                                 {
-                                    properties.Add(new FPGAArrayReadProperty<int>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayReadProperty<int>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 break;
                             case lvbitx.Datatype.Uint32:
                                 if (!reg.Indicator)
                                 {
-                                    properties.Add(new FPGAArrayWriteProperty<uint>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayWriteProperty<uint>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 else
                                 {
-                                    properties.Add(new FPGAArrayReadProperty<uint>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayReadProperty<uint>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 break;
                             case lvbitx.Datatype.Int64:
                                 if (!reg.Indicator)
                                 {
-                                    properties.Add(new FPGAArrayWriteProperty<long>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayWriteProperty<long>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 else
                                 {
-                                    properties.Add(new FPGAArrayReadProperty<long>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayReadProperty<long>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 break;
                             case lvbitx.Datatype.Uint64:
                                 if (!reg.Indicator)
                                 {
-                                    properties.Add(new FPGAArrayWriteProperty<ulong>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayWriteProperty<ulong>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 else
                                 {
-                                    properties.Add(new FPGAArrayReadProperty<ulong>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayReadProperty<ulong>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 break;
                             case lvbitx.Datatype.Float:
                                 if (!reg.Indicator)
                                 {
-                                    properties.Add(new FPGAArrayWriteProperty<float>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayWriteProperty<float>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 else
                                 {
-                                    properties.Add(new FPGAArrayReadProperty<float>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayReadProperty<float>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 break;
                             case lvbitx.Datatype.Double:
                                 if (!reg.Indicator)
                                 {
-                                    properties.Add(new FPGAArrayWriteProperty<double>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayWriteProperty<double>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 else
                                 {
-                                    properties.Add(new FPGAArrayReadProperty<double>(session, reg.Offset, reg.Size) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayReadProperty<double>(session, reg.Offset, reg.Size)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 break;
                             case lvbitx.Datatype.FXP:
                                 if (!reg.Indicator)
                                 {
-                                    properties.Add(new FPGAArrayFXPWriteProperty(session, reg.Offset, reg.Size, reg.FxpTypeInfo, _FXPConvert) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayFXPWriteProperty(session, reg.Offset, reg.Size, reg.FxpTypeInfo, _FXPConvert)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 else
                                 {
-                                    properties.Add(new FPGAArrayFXPReadProperty(session, reg.Offset, reg.Size, reg.FxpTypeInfo, _FXPConvert) { Name = reg.Name });
+                                    properties.Add(new FPGAArrayFXPReadProperty(session, reg.Offset, reg.Size, reg.FxpTypeInfo, _FXPConvert)
+                                    {
+                                        Name = reg.Name,
+                                        SizeInBits = reg.SizeInBits,
+                                    });
                                 }
                                 break;
                             case lvbitx.Datatype.Array:

+ 20 - 8
NIFPGA/FPGAArrayFXPReadProperty.cs

@@ -4,28 +4,40 @@ namespace NIFPGA
 {
     public sealed class FPGAArrayFXPReadProperty : FPGABaseProperty
     {
-        Interop.NiFpgaDll_ReadArrayU64 Read;
+        Interop.NiFpgaDll_ReadArrayU8 Read;
         private NiFpga_FxpTypeInfo _TypeInfo;
         private IFxpConvert _Convert;
+        private byte[] tempbuffer = new byte[0];
         private ulong[] tempvalue = new ulong[0];
-        private float[] doubles = new float[0];
+        private double[] doubles = new double[0];
         internal FPGAArrayFXPReadProperty(FPGASession session, uint indicator, uint count, NiFpga_FxpTypeInfo typeInfo, IFxpConvert convert) : base(session, indicator, true)
         {
             _Convert = convert;
             Count = count;
             tempvalue = new ulong[count];
-            doubles = new float[count];
+            doubles = new double[count];
             _TypeInfo = typeInfo;
-            Read = _Session.GetDelegate<Interop.NiFpgaDll_ReadArrayU64>();
+            tempbuffer = new byte[(int)Math.Ceiling(typeInfo.wordLength * count / 8.0)];
+            Read = _Session.GetDelegate<Interop.NiFpgaDll_ReadArrayU8>();
         }
 
-        private float[] GetData()
+        private double[] GetData()
         {
-            _Session.CheckResult(Read(_Session.Session, Indicator, ref tempvalue[0], Count));
-            _Convert.FxpConvertToFloat(ref tempvalue[0], _TypeInfo, ref doubles[0], Count);
+            _Session.CheckResult(Read(_Session.Session, Indicator, ref tempbuffer[0], (uint)tempbuffer.Length));
+            string s = string.Empty;
+            for (int i = 0; i < tempbuffer.Length; i++)
+            {
+                s += tempbuffer[i].ToString("b").PadLeft(8, '0');
+            }
+            for (int i = 0; i < tempvalue.Length; i++)
+            {
+                tempvalue[i] = System.Convert.ToUInt64(s.Substring(i * _TypeInfo.wordLength, _TypeInfo.wordLength), 2);
+            }
+
+            _Convert.FxpConvertToDouble(ref tempvalue[0], _TypeInfo, ref doubles[0], Count);
             return doubles;
         }
         public uint Count { get; }
-        public float[] Value { get => GetData(); }
+        public double[] Value { get => GetData(); }
     }
 }

+ 35 - 13
NIFPGA/FPGAArrayFXPWriteProperty.cs

@@ -1,38 +1,60 @@
 using FxpConvert.Common;
+using System.Reflection;
 
 namespace NIFPGA
 {
     public sealed class FPGAArrayFXPWriteProperty : FPGABaseProperty
     {
-        Interop.NiFpgaDll_ReadArrayU64 Read;
-        Interop.NiFpgaDll_WriteArrayU64 Write;
+        Interop.NiFpgaDll_ReadArrayU8 Read;
+        Interop.NiFpgaDll_WriteArrayU8 Write;
         private NiFpga_FxpTypeInfo _TypeInfo;
         private IFxpConvert _Convert;
+        private byte[] tempbuffer = new byte[0];
         private ulong[] tempvalue = new ulong[0];
-        private float[] doubles = new float[0];
+        private double[] doubles = new double[0];
         internal FPGAArrayFXPWriteProperty(FPGASession session, uint indicator, uint count,NiFpga_FxpTypeInfo typeInfo, IFxpConvert convert) : base(session, indicator,false)
         {
             _Convert = convert;
             Count = count;
             tempvalue = new ulong[count];
-            doubles = new float[count];
+            doubles = new double[count];
             _TypeInfo = typeInfo;
-            Read = _Session.GetDelegate<Interop.NiFpgaDll_ReadArrayU64>();
-            Write = _Session.GetDelegate<Interop.NiFpgaDll_WriteArrayU64>();
+            tempbuffer = new byte[(int)Math.Ceiling(typeInfo.wordLength*count / 8.0)];
+            Read = _Session.GetDelegate<Interop.NiFpgaDll_ReadArrayU8>();
+            Write = _Session.GetDelegate<Interop.NiFpgaDll_WriteArrayU8>();
         }
-        private float[] GetData()
+        private double[] GetData()
         {
-            _Session.CheckResult(Read(_Session.Session, Indicator, ref tempvalue[0], Count));
-            _Convert.FxpConvertToFloat(ref tempvalue[0], _TypeInfo, ref doubles[0], Count);
+            _Session.CheckResult(Read(_Session.Session, Indicator, ref tempbuffer[0], (uint)tempbuffer.Length));
+            string s = string.Empty;
+            for(int i=0;i<tempbuffer.Length;i++)
+            {
+                s += tempbuffer[i].ToString("b").PadLeft(8, '0');
+            }
+            for(int i=0;i<tempvalue.Length;i++)
+            {
+                tempvalue[i] = System.Convert.ToUInt64(s.Substring(i * _TypeInfo.wordLength, _TypeInfo.wordLength), 2);
+            }
+
+            _Convert.FxpConvertToDouble(ref tempvalue[0], _TypeInfo, ref doubles[0], Count);
             return doubles;
         }
-        private void SetData(float[] values)
+        private void SetData(double[] values)
         {
             if (values.Length != Count) return;
-            _Convert.FloatConvertToDxp(ref values[0], _TypeInfo, ref tempvalue[0], Count);
-            _Session.CheckResult(Write(_Session.Session,Indicator, ref tempvalue[0], Count));
+            _Convert.DoubleConvertToDxp(ref values[0], _TypeInfo, ref tempvalue[0], Count);
+            string s = string.Empty;
+            for(int i=0;i<tempvalue.Length;i++)
+            {
+                s += tempvalue[i].ToString("b").PadLeft(64, '0').Substring(64 - _TypeInfo.wordLength, _TypeInfo.wordLength);
+            }
+            for(int i=0;i< tempbuffer.Length;i++)
+            {
+                tempbuffer[i] = System.Convert.ToByte(s.Substring(i * 8, Math.Min(8, s.Length - i * 8)),2);
+            }
+            _Session.CheckResult(Write(_Session.Session,Indicator, ref tempbuffer[0], (uint)tempbuffer.Length));
         }
         public uint Count { get; }
-        public float[] Value { get => GetData(); set => SetData(value); }
+        public double[] Value { get => GetData(); set => SetData(value); }
     }
 }

+ 1 - 0
NIFPGA/FPGABaseProperty.cs

@@ -13,6 +13,7 @@ namespace NIFPGA
             Indicator = indicator;
             IsIndicator= isIndicator;
         }
+        public uint SizeInBits { get; init; }
         public Boolean IsIndicator { get; }
         public uint Indicator { get; }
         public string Name { get; init; }

+ 4 - 4
NIFPGA/FPGAFXPReadProperty.cs

@@ -13,14 +13,14 @@ namespace NIFPGA
             _Convert = convert;
             Read = _Session.GetDelegate<Interop.NiFpgaDll_ReadU64>();
         }
-        private float GetValue()
+        private double GetValue()
         {
             ulong value = 0;
-            float temp = 0;
+            double temp = 0;
             _Session.CheckResult(Read(_Session.Session, Indicator, ref value));
-            _Convert.FxpConvertToFloat(ref value, _TypeInfo, ref temp, 1);
+            _Convert.FxpConvertToDouble(ref value, _TypeInfo, ref temp, 1);
             return temp;
         }
-        public float Value => GetValue();
+        public double Value => GetValue();
     }
 }

+ 6 - 6
NIFPGA/FPGAFXPWriteProperty.cs

@@ -15,20 +15,20 @@ namespace NIFPGA
             Read = _Session.GetDelegate<Interop.NiFpgaDll_ReadU64>();
             Write = _Session.GetDelegate<Interop.NiFpgaDll_WriteU64>();
         }
-        private float GetValue()
+        private double GetValue()
         {
             ulong value = 0;
-            float temp = 0;
+            double temp = 0;
             _Session.CheckResult(Read(_Session.Session, Indicator, ref value));
-            _Convert.FxpConvertToFloat(ref value, _TypeInfo, ref temp, 1);
+            _Convert.FxpConvertToDouble (ref value, _TypeInfo, ref temp, 1);
             return temp;
         }
-        private void SetValue(float value)
+        private void SetValue(double value)
         {
             ulong temp = 0;
-            _Convert.FloatConvertToDxp(ref value, _TypeInfo, ref temp, 1);
+            _Convert.DoubleConvertToDxp(ref value, _TypeInfo, ref temp, 1);
             _Session.CheckResult(Write(_Session.Session, Indicator, temp));
         }
-        public float Value { get => GetValue(); set => SetValue(value); }
+        public double Value { get => GetValue(); set => SetValue(value); }
     }
 }

+ 8 - 4
NIFPGA/Fifo.cs

@@ -31,12 +31,16 @@ namespace NIFPGA
             _Session.CheckResult(_Session.GetDelegate<Interop.NiFpgaDll_GetFifoPropertyU32>()(_Session.Session, fifosession, Interop.NiFpga_FifoProperty.NiFpga_FifoProperty_BytesPerElement, ref _BytesPerElement));
         }
 
+        public void GetDmaBuffer(ref nint ptr)
+        {
+            _Session.CheckResult(_Session.GetDelegate<Interop.NiFpgaDll_GetFifoPropertyPtr>()(_Session.Session, FifoSession, Interop.NiFpga_FifoProperty.NiFpga_FifoProperty_HostBuffer, ref ptr));
+        }
 
-        public uint ElementsCurrentlyAcquired =>GetElementsCurrentlyAcquired();
-        private uint GetElementsCurrentlyAcquired()
+        public ulong ElementsCurrentlyAcquired =>GetElementsCurrentlyAcquired();
+        private ulong GetElementsCurrentlyAcquired()
         {
-            uint value = 0;
-            _Session.CheckResult(_Session.GetDelegate<Interop.NiFpgaDll_GetFifoPropertyU32>()(_Session.Session, FifoSession, Interop.NiFpga_FifoProperty.NiFpga_FifoProperty_ElementsCurrentlyAcquired, ref value));
+            ulong value = 0;
+            _Session.CheckResult(_Session.GetDelegate<Interop.NiFpgaDll_GetFifoPropertyU64>()(_Session.Session, FifoSession, Interop.NiFpga_FifoProperty.NiFpga_FifoProperty_ElementsCurrentlyAcquired, ref value));
             return value;
         }
         public string Name { get; init; } = string.Empty;

+ 1 - 1
NIFPGA/NiFpga_FifoFlowControl.cs

@@ -1,6 +1,6 @@
 namespace NIFPGA
 {
-    public enum NiFpga_FifoFlowControl
+    public enum NiFpga_FifoFlowControl:int
     {
 
         /// NiFpga_FifoFlowControl_Disabled -> 1

+ 1 - 1
NIFPGA/NiFpga_HostBufferType.cs

@@ -1,6 +1,6 @@
 namespace NIFPGA
 {
-    public enum NiFpga_HostBufferType
+    public enum NiFpga_HostBufferType:int
     {
 
         /// NiFpga_HostBufferType_AllocatedByRIO -> 1

+ 2 - 2
OxyPlot/OxyPlot.Avalonia/Tracker/TrackerControl.cs

@@ -59,7 +59,7 @@ namespace OxyPlot.Avalonia
         /// <summary>
         /// Identifies the <see cref="CornerRadius"/> dependency property.
         /// </summary>
-        public static readonly StyledProperty<double> CornerRadiusProperty = AvaloniaProperty.Register<TrackerControl, double>(nameof(CornerRadius), 0.0);
+        public static new readonly StyledProperty<double> CornerRadiusProperty = AvaloniaProperty.Register<TrackerControl, double>(nameof(CornerRadius), 0.0);
 
         /// <summary>
         /// Identifies the <see cref="Distance"/> dependency property.
@@ -239,7 +239,7 @@ namespace OxyPlot.Avalonia
         /// <summary>
         /// Gets or sets the corner radius (only used when ShowPoint=<c>false</c>).
         /// </summary>
-        public double CornerRadius
+        public new double CornerRadius
         {
             get
             {

+ 7 - 0
Shaker.Model/AnalogType.cs

@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.ComponentModel;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
@@ -9,15 +10,21 @@ namespace Shaker.Models
     public enum AnalogType
     {
         [AnalogUnit("mm")]
+        [Description("Displacement")]
         Displacement,
+        [Description("Acceleration")]
         [AnalogUnit("g")]
         Acceleration,
+        [Description("ValvePressure")]
         [AnalogUnit("MPa")]
         Force,
+        [Description("OutInputSignal")]
         [AnalogUnit("V")]
         OutSignal,
+        [Description("ValveDriveSignal")]
         [AnalogUnit("V")]
         Driver,
+        [Description("ValveDriveGiven")]
         [AnalogUnit("mm")]
         GivenDriver,
     }

+ 4 - 4
Shaker.Model/Models/RandomConfigModel.cs

@@ -3,21 +3,21 @@
     public class RandomConfigModel : BaseModel
     {
         public readonly uint SpectrumItemsCount = 20;
-        public float HanningWindowCompensationCoefficient = 1.5f;
+        public double HanningWindowCompensationCoefficient = 1.5f;
         public uint LinearAverage = 4;
         public uint ExponentialAverage = 8;
         public readonly uint RandomSampleRate = 2000;
         public RandomMaxFrequency MaxFrequency = RandomMaxFrequency.Frequeny_200;
         public AccelerationSynthesisType SynthesisType = AccelerationSynthesisType.Synthesis;
-        public float MinFrequency = 1f;
+        public double MinFrequency = 1f;
         public SpectrumLines SpectrumLines = SpectrumLines.SpectrumLines_200;
-        public float Sigma = 3;
+        public double Sigma = 3;
         public RandomIdentifyModel Identify = new RandomIdentifyModel();
         public List<RandomSpectrumItemModel> SpectrumItems = new List<RandomSpectrumItemModel>();
         public List<RandomPlanItemModel> PlanItems = new List<RandomPlanItemModel>();
         public uint StopLins = 160;
         public uint WarnLines = 120;
-        public float StopRMS = 6;
+        public double StopRMS = 6;
         public override object Clone()
         {
             return this.CloneBase();

+ 6 - 6
Shaker.Model/Models/RandomSpectrumItemModel.cs

@@ -3,13 +3,13 @@ namespace Shaker.Models
 {
     public class RandomSpectrumItemModel : BaseModel
     {
-        public float Frequency = 0;
+        public double Frequency = 0;
         public RandomValueType ValueType = RandomValueType.Value;
-        public float Value = 0;
-        public float UpStop = 6;
-        public float UpWarn = 3;
-        public float DownStop = -6;
-        public float DownWarn = -3;
+        public double Value = 0;
+        public double UpStop = 6;
+        public double UpWarn = 3;
+        public double DownStop = -6;
+        public double DownWarn = -3;
         public override object Clone()
         {
             return this.CloneBase();

+ 12 - 12
Shaker.Model/Models/ShakerConfigModel.cs

@@ -3,7 +3,7 @@
     public class ShakerConfigModel : BaseModel
     {
         public AccelerationSynthesisType SynthesisType = AccelerationSynthesisType.Synthesis; 
-        public float OutSignalGain = 1;
+        public double OutSignalGain = 1;
         public uint MaxRiseCount = 120000;
         public uint MaxZeroChangedCount = 40000;
         public uint MaxSignalCount = 20000;
@@ -12,25 +12,25 @@
         public uint MaxAdjustCount = 4000;
         public uint MaxFallCount = 60000;
         public uint StartCount = 70000;
-        public float InitialLocation = -45;
+        public double InitialLocation = -45;
         public uint SampleRate = 4000;
         public uint FPGAClock = 40_000_000;
-        public float MaxFrequency = 200f;
-        public float MinFrequency = 0.1f;
+        public double MaxFrequency = 200f;
+        public double MinFrequency = 0.1f;
         public List<AnalogSignalConfigModel> AnalogSignalConfigs = new List<AnalogSignalConfigModel>();
 
 
-        public float MaxOutInput = 16;
-        public float MaxAcceleration = 10;
-        public float MaxDisplacement = 10;
-        public float MaxDriver = 10;
-        public float MaxJitterAcceleration = 32;
-        public float MaxJitterDisplacement = 1000;
-        public float MaxVelocity = 0.6f;
+        public double MaxOutInput = 16;
+        public double MaxAcceleration = 10;
+        public double MaxDisplacement = 10;
+        public double MaxDriver = 10;
+        public double MaxJitterAcceleration = 32;
+        public double MaxJitterDisplacement = 1000;
+        public double MaxVelocity = 0.6f;
 
 
 
-        public float DisplacementSensitivity = 100;
+        public double DisplacementSensitivity = 100;
         public List<AccelerationConfigModel> AccelerationConfigs = new List<AccelerationConfigModel>();
         public override object Clone()
         {

+ 4 - 4
Shaker.Model/Models/SineDataModel.cs

@@ -2,10 +2,10 @@
 {
     public class SineDataModel :BaseModel, IResultDataModel
     {
-        public float TotalTime = 0;
-        public float RunTime = 0;
-        public float CurrentFrequency = 0;
-        public float CurrentAcceleration = 0;
+        public double TotalTime = 0;
+        public double RunTime = 0;
+        public double CurrentFrequency = 0;
+        public double CurrentAcceleration = 0;
         public uint SweepIndex = 0;
         public SweepDirection SweepDirection = SweepDirection.Up;
         public SweepStep SweepStep = SweepStep.Start;

+ 14 - 14
Shaker.Model/Models/SweepConfigModel.cs

@@ -2,27 +2,27 @@
 {
     public class SweepConfigModel : BaseModel
     {
-        public readonly float Increment = 0.01f;
+        public readonly double Increment = 0.01f;
         public readonly int MaxSweepItemCount = 50;
         public uint SweepCount = 1;
         public SweepType SweepType = SweepType.Log;
         public SweepDirection SweepDirection = SweepDirection.Up;
         public SignalType SignalType = SignalType.Sweep;
-        public float StartFrequency = 0.1f;
-        public float EndFrequency = 200f;
-        public float OnceSweepTime = 1;
-        public float SweepSpeed = 1;
+        public double StartFrequency = 0.1f;
+        public double EndFrequency = 200f;
+        public double OnceSweepTime = 1;
+        public double SweepSpeed = 1;
 
-        public float SweepStartLevel = 0.5f;
-        public float CrossoverPoint = 5;
-        public float SweepLevelGain = 0.99f;
-        public float LowFrequencyMinCorrect = 0.97f;
-        public float LowFrequencyMaxCorrect = 1.01f;
-        public float HigthFrequencyMinCorrect = 0.9f;
-        public float HigthFrequencyMaxCorrect = 1.1f;
+        public double SweepStartLevel = 0.5f;
+        public double CrossoverPoint = 5;
+        public double SweepLevelGain = 0.99f;
+        public double LowFrequencyMinCorrect = 0.97f;
+        public double LowFrequencyMaxCorrect = 1.01f;
+        public double HigthFrequencyMinCorrect = 0.9f;
+        public double HigthFrequencyMaxCorrect = 1.1f;
         public int SelectChannel = 0;
-        public float LowFreq = 3;
-        public float HighFreq = 6;
+        public double LowFreq = 3;
+        public double HighFreq = 6;
 
         public List<SweepItemModel> SweepItems = new List<SweepItemModel>();
         public override object Clone()

+ 6 - 6
Shaker.Model/Models/SweepItemModel.cs

@@ -9,12 +9,12 @@ namespace Shaker.Models
     public class SweepItemModel : BaseModel
     {
         public SweepValueType SweepValueType = SweepValueType.FixedDisplacement;
-        public float Value = 0;
-        public float Frequency = 0;
-        public float UpStop = 6;
-        public float UpWarn = 3;
-        public float DownStop = -6;
-        public float DownWarn = -3;
+        public double Value = 0;
+        public double Frequency = 0;
+        public double UpStop = 6;
+        public double UpWarn = 3;
+        public double DownStop = -6;
+        public double DownWarn = -3;
         public override object Clone()
         {
             return this.CloneBase();

+ 2 - 2
Shaker.Model/Models/ValveConfigItemModel.cs

@@ -2,8 +2,8 @@
 {
     public class ValveConfigItemModel : BaseModel
     {
-        public float Bias = 0;
-        public float OpenLoopDrive = 0;
+        public double Bias = 0;
+        public double OpenLoopDrive = 0;
         public override object Clone()
         {
             return this.CloneBase();

+ 34 - 34
Shaker.Model/Tools/Tools.cs

@@ -10,7 +10,7 @@ namespace Shaker.Models.Tools
 {
     public static  class Tools
     {
-        public static void CalcSlope(float[] x, float[] y,ref float k,ref float b)
+        public static void CalcSlope(double[] x, double[] y,ref double k,ref double b)
         {
             if(x ==null || y==null || x.Length!=2||y.Length!=2)
             {
@@ -21,7 +21,7 @@ namespace Shaker.Models.Tools
             k = (y[1] - y[0]) / (x[1] - x[0]);
             b = y[0] - x[0] * k;
         }
-        public static int FindFrequencyIndex(this SweepConfigModel model,float freq)
+        public static int FindFrequencyIndex(this SweepConfigModel model, double freq)
         {
             if (model.SweepItems.Count < 2) return -1;
             uint uintfreq = (uint)(freq * 100);
@@ -32,7 +32,7 @@ namespace Shaker.Models.Tools
             return model.SweepItems.Count - 1;
         }
 
-        public static void CalcAmpt(this SweepConfigModel model, float freq,ref float value,ref float upstop,ref float upwarn,ref float downstop,ref float downwarn)
+        public static void CalcAmpt(this SweepConfigModel model, double freq,ref double value,ref double upstop,ref double upwarn,ref double downstop,ref double downwarn)
         {
             int index = model.FindFrequencyIndex(freq);
             if (index == -1) return;
@@ -41,10 +41,10 @@ namespace Shaker.Models.Tools
             switch (nowmodel.SweepValueType)
             {
                 case SweepValueType.FixedDisplacement:
-                    value = freq * nowmodel.Value * freq * 4 * MathF.PI *MathF.PI/ 9800f;
+                    value = freq * nowmodel.Value * freq * 4 * Math.PI *Math.PI/ 9800f;
                     break;
                 case SweepValueType.FixedVelocity:
-                    value = freq * 2 * MathF.PI * nowmodel.Value / 9.8f;
+                    value = freq * 2 * Math.PI * nowmodel.Value / 9.8f;
                     break;
                 case SweepValueType.FixedAcceleration:
                     value = nowmodel.Value;
@@ -58,24 +58,24 @@ namespace Shaker.Models.Tools
                         else
                         {
                             SweepItemModel nextmodel = model.SweepItems[index + 1];
-                            float k = 0;
-                            float b = 0;
-                            Tools.CalcSlope(new float[] { MathF.Log10(nowmodel.Frequency), MathF.Log10(nextmodel.Frequency) }, new float[] { MathF.Log10(nowmodel.Value), MathF.Log10(nextmodel.Value) }, ref k, ref b);
-                            value = MathF.Pow(10, k *MathF.Log10(freq) + b);
+                            double k = 0;
+                            double b = 0;
+                            Tools.CalcSlope(new double[] { Math.Log10(nowmodel.Frequency), Math.Log10(nextmodel.Frequency) }, new double[] { Math.Log10(nowmodel.Value), Math.Log10(nextmodel.Value) }, ref k, ref b);
+                            value = Math.Pow(10, k *Math.Log10(freq) + b);
                         }
                     }
                     break;
             }
-            upstop = MathF.Pow(10, nowmodel.UpStop / 20) * value;
-            upwarn = MathF.Pow(10, nowmodel.UpWarn / 20) * value;
-            downstop = MathF.Pow(10, nowmodel.DownStop / 20) * value;
-            downwarn = MathF.Pow(10, nowmodel.DownWarn / 20) * value;
+            upstop = Math.Pow(10, nowmodel.UpStop / 20) * value;
+            upwarn = Math.Pow(10, nowmodel.UpWarn / 20) * value;
+            downstop = Math.Pow(10, nowmodel.DownStop / 20) * value;
+            downwarn = Math.Pow(10, nowmodel.DownWarn / 20) * value;
         }
-        public static float CalcAmpt(this SweepConfigModel model, float freq)
+        public static double CalcAmpt(this SweepConfigModel model, double freq)
         {
             int index = model.FindFrequencyIndex(freq);
             if (index == -1) return 0;
-            float value = 0;
+            double value = 0;
             SweepItemModel nowmodel = model.SweepItems[index];
             switch (nowmodel.SweepValueType)
             {
@@ -97,19 +97,19 @@ namespace Shaker.Models.Tools
                         else
                         {
                             SweepItemModel nextmodel = model.SweepItems[index + 1];
-                            float k = 0;
-                            float b = 0;
-                            Tools.CalcSlope(new float[] { MathF.Log10(nowmodel.Frequency), MathF.Log10(nextmodel.Frequency) }, new float[] { MathF.Log10(nowmodel.Value), MathF.Log10(nextmodel.Value) }, ref k, ref b);
-                            value = MathF.Pow(10, k * freq + b);
+                            double k = 0;
+                            double b = 0;
+                            Tools.CalcSlope(new double[] { Math.Log10(nowmodel.Frequency), Math.Log10(nextmodel.Frequency) }, new double[] { Math.Log10(nowmodel.Value), Math.Log10(nextmodel.Value) }, ref k, ref b);
+                            value = Math.Pow(10, k * freq + b);
                         }
                     }
                     break;
             }
             return value;
         }
-        public static float TimeToOCT(this SweepConfigModel model,float time)
+        public static double TimeToOCT(this SweepConfigModel model, double time)
         {
-            float oct = 0;
+            double oct = 0;
             switch(model.SweepType)
             {
                 case SweepType.Linear:
@@ -117,14 +117,14 @@ namespace Shaker.Models.Tools
                     break;
                 case SweepType.Log:
                 default:
-                    oct = MathF.Log2(model.EndFrequency / model.StartFrequency) / time * 60;
+                    oct = Math.Log2(model.EndFrequency / model.StartFrequency) / time * 60;
                     break;
             }
             return oct;
         }
-        public static float OCTToTime(this SweepConfigModel model,float oct)
+        public static double OCTToTime(this SweepConfigModel model, double oct)
         {
-            float time = 0;
+            double time = 0;
             switch(model.SweepType)
             {
                 case SweepType.Linear:
@@ -132,33 +132,33 @@ namespace Shaker.Models.Tools
                     break;
                 case SweepType.Log:
                 default:
-                    time = MathF.Log2(model.EndFrequency / model.StartFrequency) / oct * 60;
+                    time = Math.Log2(model.EndFrequency / model.StartFrequency) / oct * 60;
                     break;
             }
             return time;
         }
 
-        public static float DisplacementToVelocity(float displacement,float freq)
+        public static double DisplacementToVelocity(double displacement, double freq)
         {
             return displacement * 2 * MathF.PI * freq / 1000;
         }
-        public static float DisplacementToAcceleration(float displacement, float freq)
+        public static double DisplacementToAcceleration(double displacement, double freq)
         {
             return displacement * 2 * MathF.PI * freq * 2*MathF.PI*freq / 9800;
         }
-        public static float VelocityToAcceleration(float velocity, float freq)
+        public static double VelocityToAcceleration(double velocity, double freq)
         {
-            return velocity * 2 * MathF.PI * freq / 9.8f;
+            return velocity * 2 * MathF.PI * freq / 9.8;
         }
-        public static float VelocityToDisplacement(float velocity, float freq)
+        public static double VelocityToDisplacement(double velocity, double freq)
         {
             return velocity * 1000 / (2 * MathF.PI * freq);
         }
-        public static float AccelerationToDisplacement(float acceleration, float freq)
+        public static double AccelerationToDisplacement(double acceleration, double freq)
         {
             return acceleration * 9800 / (2 * MathF.PI * freq * 2 * MathF.PI * freq);
         }
-        public static float AccelerationToVelocity(float acceleration, float freq)
+        public static double AccelerationToVelocity(double acceleration, double freq)
         {
             return acceleration * 9.8f / (2 * MathF.PI * freq );
         }
@@ -209,9 +209,9 @@ namespace Shaker.Models.Tools
         /// <param name="maxCount">最大计数</param>
         /// <returns></returns>
 
-        public static float CalcInterval(uint maxCount)
+        public static double CalcInterval(uint maxCount)
         {
-            return 1f / (maxCount << 1);
+            return 1d / (maxCount << 1);
         }
         /// <summary>
         /// 二维数组转置

+ 2 - 0
Shaker/OilSource/OilSource.cs

@@ -1,5 +1,6 @@
 using MessagePack.Formatters;
 using Shaker.Models;
+using ShakerService.Tools;
 using System;
 using System.Collections.Generic;
 using System.Diagnostics.CodeAnalysis;
@@ -281,6 +282,7 @@ namespace ShakerService.OilSource
                     }
                 }
             });
+            Log.Default.Info("初始化油源参数");
         }
 
         private void Timer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)

+ 9 - 6
Shaker/Service.RTInit.cs

@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using ShakerService.Tools;
 using ShakerService.ViewModel;
 
 namespace ShakerService
@@ -16,6 +17,7 @@ namespace ShakerService
             ServiceShakerConfigViewModel.Instance.SetFpga();
             ServiceShakerControlViewModel.Instance.SetFpga();
             ShakerFpga.Instance.Run();
+            Log.Default.Info("初始化FPGA");
             RTInitFifo();
         }
         private void RTInitFifo()
@@ -26,12 +28,13 @@ namespace ShakerService
             ShakerFpga.Instance.Read.HostBufferSize = ServiceShakerConfigViewModel.Instance.SampleRate << 1;
             ShakerFpga.Instance.Read.CommitConfiguration();
             ShakerFpga.Instance.Read.Start();
-            ReadedDataCache = new float[ServiceShakerConfigViewModel.Instance.ChannelCount*ServiceShakerConfigViewModel.Instance.SampleRate];
-            DataCache = new float[ServiceShakerConfigViewModel.Instance.ChannelCount,ServiceShakerConfigViewModel.Instance.SampleRate];
-            SensitivityValues = Enumerable.Repeat(1f, (int)ServiceShakerConfigViewModel.Instance.ChannelCount).ToArray();
-            SensitivityValues[0] = ServiceShakerConfigViewModel.Instance.DisplacementSensitivity / 1000f;
-            SensitivityValues[1] = SensitivityValues[0];
-            SensitivityValues[2] = ServiceShakerConfigViewModel.Instance.AccelerationSensitivity / 1000f;
+            ServiceDataCacheViewModel.Instance.ReadedDataCache = new float[ServiceShakerConfigViewModel.Instance.ChannelCount*ServiceShakerConfigViewModel.Instance.SampleRate];
+            ServiceDataCacheViewModel.Instance.DataCache = new float[ServiceShakerConfigViewModel.Instance.ChannelCount,ServiceShakerConfigViewModel.Instance.SampleRate];
+            ServiceDataCacheViewModel.Instance.SensitivityValues = Enumerable.Repeat(1f, (int)ServiceShakerConfigViewModel.Instance.ChannelCount).ToArray();
+            ServiceDataCacheViewModel.Instance.SensitivityValues[0] = 1000f / (float)ServiceShakerConfigViewModel.Instance.DisplacementSensitivity;
+            ServiceDataCacheViewModel.Instance.SensitivityValues[1] = ServiceDataCacheViewModel.Instance.SensitivityValues[0];
+            ServiceDataCacheViewModel.Instance.SensitivityValues[2] = 1000f / (float)ServiceShakerConfigViewModel.Instance.AccelerationSensitivity;
+            Log.Default.Info("初始化Fifo");
         }
     }
 }

+ 18 - 5
Shaker/Service.cs

@@ -19,6 +19,7 @@ namespace ShakerService
         public Service()
         {
             Communication.Instance.StartService("0,0,0,0",ServiceConfigViewModel.Instance.Port);
+            Log.Default.Info($"监听端口{ServiceConfigViewModel.Instance.Port}");
             this.GetType().Assembly.GetTypes()
                 .Where(x => x.IsAnsiClass && !x.IsAbstract && x.GetInterface(typeof(IServiceViewModel<IModel>).Name)!=null)
                 .ToList()
@@ -37,6 +38,7 @@ namespace ShakerService
         private System.Timers.Timer UpAmpttimer = new System.Timers.Timer();
         private System.Timers.Timer ReadConfigTimer = new System.Timers.Timer();
         private AutoResetEvent WaitTriggerLock = new AutoResetEvent(false);
+        private CancellationTokenSource deviceDiscoveryTokenSource = new CancellationTokenSource();
         /// <summary>
         /// 油源循环锁,当油源与PLC断开连接后自动阻塞轮询线程
         /// </summary>
@@ -45,15 +47,17 @@ namespace ShakerService
         {
             System.Net.Sockets.UdpClient udpClient = new System.Net.Sockets.UdpClient(Topic.DISCOVERYPORT);
             udpClient.JoinMulticastGroup(IPAddress.Parse("239.1.0.2"));
-            while(!tokenSource.IsCancellationRequested)
+            Log.Default.Info("网络发现服务启动");
+            deviceDiscoveryTokenSource = new CancellationTokenSource();
+            while (!deviceDiscoveryTokenSource.IsCancellationRequested)
             {
-                var result = await  udpClient.ReceiveAsync(tokenSource.Token);
+                var result = await udpClient.ReceiveAsync(deviceDiscoveryTokenSource.Token);
                 try
                 {
                     var msg = result.Buffer.GetValue<SearchDeviceModel>();
                     if(msg!=null)
                     {
-                        Console.WriteLine("接收到广播信息");
+                        Log.Default.Info($"{result.RemoteEndPoint.Address.ToString()}开始扫描");
                         var networks = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
                         var aa = networks.Where(x => x.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up).Select(x => x.GetIPProperties().UnicastAddresses).SelectMany(x => x).Where(x => x.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).ToList();
                         
@@ -74,6 +78,8 @@ namespace ShakerService
                         {
                             resultDevice.DeviceInfoModel.IP = aa[index].Address.ToString();
                         }
+
+                        Log.Default.Debug($"返回地址{resultDevice.DeviceInfoModel.IP}:{resultDevice.DeviceInfoModel.Port}");
                         udpClient.Send(resultDevice.GetBytes(), new System.Net.IPEndPoint(IPAddress.Parse("239.1.0.2"), Topic.DISCOVERYPORT - 1));
                     }
                 }
@@ -98,6 +104,8 @@ namespace ShakerService
             string path = System.IO.Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.lvbitx").FirstOrDefault()?? "Shaker.lvbitx";
             ShakerFpga.CreateFpga(new SIMDFxpConvert.SIMDFxpConverter());
             ShakerFpga.Instance.Open(path, "RIO0", NIFPGA.NiFpga_OpenAttribute.NiFpga_OpenAttribute_NoRun);
+            if (!ShakerFpga.Instance.LastError) Log.Default.Info($"加载bit文件:{path}成功");
+            else Log.Default.Error($"加载bit文件:{path}失败,错误信息{ShakerFpga.Instance.LastMessage}");
 
         }
         public void StartService()
@@ -113,7 +121,7 @@ namespace ShakerService
             UpAmpttimer = new System.Timers.Timer();
             UpAmpttimer.AutoReset = true;
             UpAmpttimer.Enabled = true;
-            UpAmpttimer.Interval = 45;
+            UpAmpttimer.Interval = 40;
             UpAmpttimer.Stop();
             UpAmpttimer.Elapsed += UpAmpttimer_Elapsed;
 
@@ -153,7 +161,8 @@ namespace ShakerService
 
         private void MainTask()
         {
-            while(!tokenSource.IsCancellationRequested)
+            ServiceDataCacheViewModel.Instance.IsExit = false;
+            while(!ServiceDataCacheViewModel.Instance.IsExit)
             {
                 RTInit();
                 UpAmpttimer.Stop();
@@ -178,13 +187,17 @@ namespace ShakerService
                 UpAmpttimer.Stop();
                 ReadConfigTimer.Stop();
             }
+            Log.Default.Info("停止程序");
         }
         public void StopService()
         {
+            ServiceDataCacheViewModel.Instance.IsExit = true;
             tokenSource.Cancel();
+            deviceDiscoveryTokenSource.Cancel();
         }
         private void Stop()
         {
+            ServiceDataCacheViewModel.Instance.IsExit = false;
             tokenSource.Cancel();
         }
 

+ 1 - 0
Shaker/ServiceConfig.cs

@@ -38,6 +38,7 @@ namespace ShakerService
             UpModel(config);
             Communication.Instance.DbConnection.DeleteAll<ServiceConfigModel>();
             Communication.Instance.DbConnection.Insert(config, nameof(ServiceConfigModel));
+            ServiceDataCacheViewModel.Instance.SensitivityValues = new float[AnalogCount];
         }
         static ServiceConfigViewModel()
         {

+ 2 - 0
Shaker/ShakerFpga.cs

@@ -12,6 +12,8 @@ namespace ShakerService
         private static ShakerFpga myFpga;
         [AllowNull]
         private readonly NIFPGA.FPGA fpga;
+        public bool LastError => fpga.Error;
+        public string LastMessage => fpga.Message;
         private ShakerFpga(IFxpConvert convert)
         {
             fpga = new FPGA(convert);

+ 8 - 8
Shaker/ShakerService.CalcDisplacement.cs

@@ -13,13 +13,13 @@ namespace ShakerService
     internal partial class Service
     {
         private uint _CycleCount = 0;
-        private float _D_k = 0;
-        private float _RA_k = 0;
+        private double _D_k = 0;
+        private double _RA_k = 0;
         private void CalcDisplacement()
         {
             if (ViewModel.ServiceShakerControlViewModel.Instance.SweepControlItems.Count == 0) return;
             _CycleCount++;
-            float freq = ShakerFpga.Instance.CurrentFrequency.Value;
+            double freq = ShakerFpga.Instance.CurrentFrequency.Value;
             var config = ViewModel.ServiceShakerControlViewModel.Instance.SweepControlItems.FirstOrDefault(x => freq <= x.Frequency)?.Model;
             config ??= ViewModel.ServiceShakerControlViewModel.Instance.SweepControlItems.Last().Model;
             if (config.UpDateInvert<=1 || _CycleCount % config.UpDateInvert ==0)
@@ -29,7 +29,7 @@ namespace ShakerService
                 if ((Shaker.Models.SweepStep)ShakerFpga.Instance.SweepStep.Value == Shaker.Models.SweepStep.SignalGen)
                 {
                     CalcSynthesisAmplitude(freq);
-                    float ampt = ServiceSweepConfigViewModel.Instance.SweepData.CurrentAcceleration;
+                    double ampt = ServiceSweepConfigViewModel.Instance.SweepData.CurrentAcceleration;
                     CalcNextDisp(freq, accv, ampt, _RA_k, config, ref _D_k);
                     ShakerFpga.Instance.GivenDisplacement.Value = _D_k;
                 }
@@ -40,11 +40,11 @@ namespace ShakerService
                 _RA_k = accv;
             }
         }
-        private void CalcNextDisp(float freq,float nextaccv,float a_k,float ra_k_1,SweepControlItemModel item,ref float d_k_1)
+        private void CalcNextDisp(double freq, double nextaccv, double a_k, double ra_k_1,SweepControlItemModel item,ref double d_k_1)
         {
-            float mincorrect = freq >= ServiceSweepConfigViewModel.Instance.CrossoverPoint ? ServiceSweepConfigViewModel.Instance.HigthFrequencyMinCorrect : ServiceSweepConfigViewModel.Instance.LowFrequencyMinCorrect;
-            float maxcorrect = freq >= ServiceSweepConfigViewModel.Instance.CrossoverPoint ? ServiceSweepConfigViewModel.Instance.HigthFrequencyMaxCorrect : ServiceSweepConfigViewModel.Instance.LowFrequencyMaxCorrect;
-            var v1= MathF.Pow(ra_k_1 / a_k, item.ExponentialCoefficients);
+            double mincorrect = freq >= ServiceSweepConfigViewModel.Instance.CrossoverPoint ? ServiceSweepConfigViewModel.Instance.HigthFrequencyMinCorrect : ServiceSweepConfigViewModel.Instance.LowFrequencyMinCorrect;
+            double maxcorrect = freq >= ServiceSweepConfigViewModel.Instance.CrossoverPoint ? ServiceSweepConfigViewModel.Instance.HigthFrequencyMaxCorrect : ServiceSweepConfigViewModel.Instance.LowFrequencyMaxCorrect;
+            var v1= Math.Pow(ra_k_1 / a_k, item.ExponentialCoefficients);
             var factor = d_k_1 / nextaccv;
             var changeratio = factor >= 1 ? ((item.CompressionRate + 1) / ((Math.Clamp(factor, 0.1f, 10f)) + item.CompressionRate)) : (((1 / (Math.Clamp(factor, 0.1f, 1))) + item.CompressionRate) / (item.CompressionRate + 1));
             d_k_1= Math.Clamp(d_k_1 * v1, mincorrect, maxcorrect) * changeratio;

+ 15 - 3
Shaker/ShakerService.Control.cs

@@ -1,4 +1,5 @@
 using Shaker.Models;
+using ShakerService.Tools;
 using ShakerService.ViewModel;
 using System;
 using System.Collections.Generic;
@@ -38,7 +39,7 @@ namespace ShakerService
                     ShakerControl = ServiceShakerControlViewModel.Instance.Model,
                     ShakerStatus = ServiceShakerStatusViewModel.Instance.Model,
                 };
-                Console.WriteLine($"{DateTime.Now}:Return config");
+                Log.Default.Info("同步参数");
                 return config;
             });
         }
@@ -49,6 +50,7 @@ namespace ShakerService
             Communication.Instance.Context.GetEvent(Shaker.Models.Topic.START).Subscrip((_, _) =>
             {
                 StartTrigger();
+                Log.Default.Info("开始");
             });
         }
         [PropertyInit]
@@ -57,6 +59,7 @@ namespace ShakerService
             Communication.Instance.Context.GetEvent(Shaker.Models.Topic.RISETABLE).Subscrip((_, _) =>
             {
                 RiseTable();
+                Log.Default.Info("升台面");
             });
         }
         [PropertyInit]
@@ -65,6 +68,7 @@ namespace ShakerService
             Communication.Instance.Context.GetEvent(Shaker.Models.Topic.ZEROCHANGE).Subscrip((_, e) =>
             {
                 ZeroChange((float)e.Data[0]);
+                Log.Default.Info("修改工作位:" + e.Data[0]);
             });
         }
         [PropertyInit]
@@ -73,6 +77,7 @@ namespace ShakerService
             Communication.Instance.Context.GetEvent(Shaker.Models.Topic.DROPTABLE).Subscrip((_, _) =>
             {
                 DropTable();
+                Log.Default.Info("降台面");
             });
         }
         [PropertyInit]
@@ -81,6 +86,7 @@ namespace ShakerService
             Communication.Instance.Context.GetEvent(Shaker.Models.Topic.STOPSIGNALGEN).Subscrip((_, _) =>
             {
                 StopSignalGen();
+                Log.Default.Info("停止信号发生");
             });
         }
         [PropertyInit]
@@ -89,6 +95,7 @@ namespace ShakerService
             Communication.Instance.Context.GetEvent(Shaker.Models.Topic.VALVEPOWER).Subscrip((_, e) =>
             {
                 ValvePower((bool)e.Data[0]);
+                Log.Default.Info($"阀{((bool)e.Data[0]?"上电":"去电")}");
             });
         }
         [PropertyInit]
@@ -97,6 +104,9 @@ namespace ShakerService
             Communication.Instance.Context.GetEvent(Shaker.Models.Topic.STOP).Subscrip((_, _) =>
             {
                 Stop();
+                ServiceShakerControlViewModel.Instance.SelfLoop = false;
+                ServiceShakerControlViewModel.Instance.OutSignal = false;
+                Log.Default.Info("停止");
             });
         }
         [PropertyInit]
@@ -105,6 +115,7 @@ namespace ShakerService
             Communication.Instance.Context.GetEvent(Shaker.Models.Topic.STARTSIGNALGEN).Subscrip((_, _) =>
             {
                 StartGen();
+                Log.Default.Info("开始信号发生");
             });
         }
         [PropertyInit]
@@ -113,6 +124,7 @@ namespace ShakerService
             Communication.Instance.Context.GetEvent(Shaker.Models.Topic.RESETERROR).Subscrip((_, _) =>
             {
                 ResetError();
+                Log.Default.Info("复位");
             });
         }
         [PropertyInit]
@@ -120,12 +132,12 @@ namespace ShakerService
         {
             Communication.Instance.Context.GetEvent(Shaker.Models.Topic.EXIT).Subscrip((_, _) =>
             {
-                Stop();
+                StopService();
             });
         }
         private void SendData(float[,] data)
         {
-            Console.WriteLine($"{DateTime.Now}:发送数据");
+            Log.Default.Debug("发送数据");
             Communication.Instance.Context.GetEvent(Shaker.Models.Topic.DATA).Publish(this, null, data);
         }
     }

+ 42 - 58
Shaker/ShakerService.ReadConfig.cs

@@ -12,43 +12,54 @@ namespace ShakerService
     {
         private void ReadConfig()
         {
-            switch(ServiceShakerControlViewModel.Instance.PageType)
+            if (ServiceShakerStatusViewModel.Instance.RTStatus == Shaker.Models.RTStatus.SignalGen)
             {
-                case Shaker.Models.MainPageType.RandomPage:
-                    break;
-                case Shaker.Models.MainPageType.OutSignal:
-                    break;
-                case Shaker.Models.MainPageType.SinePage:
-                    ServiceSweepConfigViewModel.Instance.SweepData.ReadFpgaData();
-                    break;
-                case Shaker.Models.MainPageType.StartPage:
-                    break;
+                switch (ServiceShakerControlViewModel.Instance.PageType)
+                {
+                    case Shaker.Models.MainPageType.RandomPage:
+                        break;
+                    case Shaker.Models.MainPageType.OutSignal:
+                        break;
+                    case Shaker.Models.MainPageType.SinePage:
+                        {
+                            ServiceSweepConfigViewModel.Instance.SweepData.CurrentFrequency = ShakerFpga.Instance.CurrentFrequency.Value;
+                            CalcSynthesisAmplitude(ServiceSweepConfigViewModel.Instance.SweepData.CurrentFrequency);
+                            CalcDowntime(ServiceSweepConfigViewModel.Instance.SweepData.CurrentFrequency);
+                            Console.WriteLine(ServiceSweepConfigViewModel.Instance.SweepData);
+                            ServiceSweepConfigViewModel.Instance.SweepData.ReadFpgaData();
+                            Console.WriteLine(ServiceSweepConfigViewModel.Instance.SweepData.ToString());
+                        }
+                        break;
+                    case Shaker.Models.MainPageType.StartPage:
+                        break;
+                }
             }
             ServiceShakerStatusViewModel.Instance.ReadFpgaData();
         }
 
-        private void CalcSynthesisAmplitude(float currentfreq)
+        private void CalcSynthesisAmplitude(double currentfreq)
         {
-            float ampt = 0;
-            float[] real = ShakerFpga.Instance.AccelerationData.Value;
-            float[] img = new float[real.Length];
+            double ampt = 0;
+            double[] real = ShakerFpga.Instance.AccelerationData.Value;
+            double[] img = new double[real.Length];
             Calc.FFT.FFT(real, img);
-            float fftacc = MathF.Sqrt(real[1] * real[1] + img[1] * img[1])/(real.Length/2);
+            double fftacc = Math.Sqrt(real[1] * real[1] + img[1] * img[1])/(real.Length/2);
             real = ShakerFpga.Instance.DisplacementData.Value;
-            img = new float[real.Length];
+            Console.WriteLine(string.Join(',', real.Select(x => x.ToString())));
+            img = new double[real.Length];
             Calc.FFT.FFT(real, img);
-            float fftdisp =DispToAcc(MathF.Sqrt(real[1] * real[1] + img[1] * img[1])/(real.Length/2),currentfreq);
-            float identifyacc = ShakerFpga.Instance.IdentifyAcceleration.Value;
-            float identifydisp = DispToAcc(ShakerFpga.Instance.IdentifyDisplacement.Value,currentfreq);
+            double fftdisp =DispToAcc(Math.Sqrt(real[1] * real[1] + img[1] * img[1])/(real.Length/2),currentfreq);
+            double identifyacc = ShakerFpga.Instance.IdentifyAcceleration.Value;
+            double identifydisp = DispToAcc(ShakerFpga.Instance.IdentifyDisplacement.Value,currentfreq);
             if(currentfreq<= ServiceSweepConfigViewModel.Instance.LowFreq)
             {
                 ampt = fftdisp;
             }
             else if(currentfreq<= ServiceSweepConfigViewModel.Instance.HighFreq)
             {
-                float disp = ServiceShakerControlViewModel.Instance.SelfLoop ? identifydisp : identifyacc;
-                float v1 = (ServiceSweepConfigViewModel.Instance.HighFreq - currentfreq) / (ServiceSweepConfigViewModel.Instance.HighFreq - ServiceSweepConfigViewModel.Instance.LowFreq) * fftdisp;
-                float v2 = (ServiceSweepConfigViewModel.Instance.HighFreq - ServiceSweepConfigViewModel.Instance.LowFreq) / (currentfreq - ServiceSweepConfigViewModel.Instance.LowFreq) * disp;
+                double disp = ServiceShakerControlViewModel.Instance.SelfLoop ? identifydisp : identifyacc;
+                double v1 = (ServiceSweepConfigViewModel.Instance.HighFreq - currentfreq) / (ServiceSweepConfigViewModel.Instance.HighFreq - ServiceSweepConfigViewModel.Instance.LowFreq) * fftdisp;
+                double v2 = (ServiceSweepConfigViewModel.Instance.HighFreq - ServiceSweepConfigViewModel.Instance.LowFreq) / (currentfreq - ServiceSweepConfigViewModel.Instance.LowFreq) * disp;
                 ampt = v1 + v2;
             }
             else
@@ -59,52 +70,25 @@ namespace ShakerService
             ShakerFpga.Instance.SynthesisAmpt.Value = ampt;
         }
 
-        private float DispToAcc(float disp,float currentFreq)
+        private double DispToAcc(double disp, double currentFreq)
         {
-            return disp * 1000 / ServiceShakerConfigViewModel.Instance.DisplacementSensitivity * MathF.Pow((currentFreq * 2 * MathF.PI), 2) / 9800 * (ServiceShakerConfigViewModel.Instance.AccelerationSensitivity / 1000);
+            return disp * 1000 / ServiceShakerConfigViewModel.Instance.DisplacementSensitivity * Math.Pow((currentFreq * 2 * Math.PI), 2) / 9800 * (ServiceShakerConfigViewModel.Instance.AccelerationSensitivity / 1000);
         }
         
 
-        private void CalcDowntime()
+        private void CalcDowntime(double currentfreq)
         {
-            float currentfreq = ServiceSweepConfigViewModel.Instance.SweepData.CurrentFrequency;
-            float value = 0;
-            float upstop = 0;
-            float upwarn = 0;
-            float downstop = 0;
-            float downwarn = 0;
+            double value = 0;
+            double upstop = 0;
+            double upwarn = 0;
+            double downstop = 0;
+            double downwarn = 0;
             ServiceSweepConfigViewModel.Instance.Model.CalcAmpt(currentfreq, ref value, ref upstop, ref upwarn, ref downstop, ref downwarn);
             ShakerFpga.Instance.LowerStop.Value = Shaker.Models.Tools.Tools.QuantitiesToVoltage(downstop, ServiceShakerConfigViewModel.Instance.AccelerationSensitivity);
             ShakerFpga.Instance.LowerWarn.Value = Shaker.Models.Tools.Tools.QuantitiesToVoltage(downwarn, ServiceShakerConfigViewModel.Instance.AccelerationSensitivity);
             ShakerFpga.Instance.UpperStop.Value = Shaker.Models.Tools.Tools.QuantitiesToVoltage(upstop, ServiceShakerConfigViewModel.Instance.AccelerationSensitivity);
             ShakerFpga.Instance.UpperWarn.Value = Shaker.Models.Tools.Tools.QuantitiesToVoltage(upwarn, ServiceShakerConfigViewModel.Instance.AccelerationSensitivity);
         }
-        /// <summary>
-        /// 差值加速度电压
-        /// </summary>
-        /// <param name="slope">斜率</param>
-        /// <param name="offset">偏移</param>
-        /// <param name="freqIndex">频率段序号</param>
-        /// <param name="LnCurrentFreq">LN的当前频率</param>
-        /// <returns></returns>
-        private float CalcAccAmpt(List<float> slope, List<float> offset,int freqIndex,float LnCurrentFreq)
-        {
-            return MathF.Exp(LnCurrentFreq * slope[freqIndex] + offset[freqIndex]);
-        }
-        /// <summary>
-        /// 获取当前频率对应的控制段
-        /// </summary>
-        /// <param name="freqControls">频率控制段,实际为频率*100后取整的值,修正由于浮点数精度问题导致的查询序号错误的问题</param>
-        /// <param name="currentFreq">当前频率</param>
-        /// <returns>控制段序号</returns>
-        private int FindFreqIndex(List<uint> freqControls,float currentFreq)
-        {
-            uint intcurrentfreq = (uint)(currentFreq * 100);
-            for(int i=0;i<freqControls.Count-1;i++)
-            {
-                if (freqControls[i] <= intcurrentfreq && intcurrentfreq <= freqControls[i + 1]) return i;
-            }
-            return freqControls.Count - 1;
-        }
+
     }
 }

+ 6 - 10
Shaker/ShakerService.ReadFifo.cs

@@ -11,24 +11,20 @@ namespace ShakerService
 {
     internal partial class Service
     {
-        private float[] ReadedDataCache = new float[0];
-        private float[,] DataCache = new float[0, 0];
-        private uint ReadDataLength = 0;
-        private float[] SensitivityValues = new float[0];
         private void ReadFifo()
         {
             while(!tokenSource.IsCancellationRequested)
             {
-                if(ShakerFpga.Instance.Write.ElementsRemaining>=ReadedDataCache.Length)
+                if(ShakerFpga.Instance.Write.ElementsRemaining>= ServiceDataCacheViewModel.Instance.ReadedDataCache.Length)
                 {
-                    ShakerFpga.Instance.Write.Read(ref ReadedDataCache[0], (uint)ReadedDataCache.Length, 100, ref ReadDataLength); 
-                    Shaker.Models.Tools.Tools.ArrayTranspose(ref ReadedDataCache[0], ref DataCache[0, 0], (int)ServiceShakerConfigViewModel.Instance.ChannelCount, (int)ServiceShakerConfigViewModel.Instance.SampleRate);
+                    ShakerFpga.Instance.Write.Read(ref ServiceDataCacheViewModel.Instance.ReadedDataCache[0], (uint)ServiceDataCacheViewModel.Instance.ReadedDataCache.Length, 100, ref ServiceDataCacheViewModel.Instance.ReadDataLength); 
+                    Shaker.Models.Tools.Tools.ArrayTranspose(ref ServiceDataCacheViewModel.Instance.ReadedDataCache[0], ref ServiceDataCacheViewModel.Instance.DataCache[0, 0], (int)ServiceShakerConfigViewModel.Instance.ChannelCount, (int)ServiceShakerConfigViewModel.Instance.SampleRate);
                     for (int i = 0; i <ServiceShakerConfigViewModel.Instance.ChannelCount; i++)
                     {
-                        if (SensitivityValues[i] == 1) continue;
-                        Calc.Multiply.Multiply(ref DataCache[i, 0], SensitivityValues[i], ServiceShakerConfigViewModel.Instance.SampleRate);
+                        if (ServiceDataCacheViewModel.Instance.SensitivityValues[i] == 1) continue;
+                        Calc.Multiply.Multiply(ref ServiceDataCacheViewModel.Instance.DataCache[i, 0], ServiceDataCacheViewModel.Instance.SensitivityValues[i], ServiceShakerConfigViewModel.Instance.SampleRate);
                     }
-                    SendData(DataCache);
+                    SendData(ServiceDataCacheViewModel.Instance.DataCache);
                     break;
                 }
                 Task.Delay(10).Wait() ;

+ 1 - 1
Shaker/ShakerService.WriteConfig.cs

@@ -43,7 +43,7 @@ namespace ShakerService
                     break;
                 case Shaker.Models.MainPageType.OutSignal:
                     ShakerFpga.Instance.OutSignal.Value = true; 
-                    ShakerFpga.Instance.SignalStop.Value = false;
+                    ShakerFpga.Instance.SignalStop.Value = false; 
                     ShakerFpga.Instance.SignalStart.Value = true;
                     break;
                 case Shaker.Models.MainPageType.SinePage:

+ 13 - 3
Shaker/Tools/Log.cs

@@ -19,17 +19,27 @@ namespace ShakerService.Tools
         }
         public void Info(string msg)
         {
-            log.Info(msg);
+            log.Info($"{DateTime.Now}:{msg}");
+            Debug(msg);
         }
         public void Debug(string msg)
         {
 #if DEBUG
-            log.Debug(msg);
+            log.Debug($"{DateTime.Now}:{msg}");
+            if(System.Console.IsOutputRedirected)
+            {
+                System.Diagnostics.Debug.WriteLine($"{DateTime.Now}:{msg}");
+            }
+            else
+            {
+                Console.WriteLine($"{DateTime.Now}:{msg}");
+            }
 #endif
         }
         public void Error(string msg)
         {
-            log.Error(msg);
+            log.Error($"{DateTime.Now}:{msg}");
+            Debug(msg);
         }
         public static Log Default { get; } = new Log();
     }

+ 2 - 2
Shaker/ViewModel/SerivceValveConfigItemViewModel.cs

@@ -13,7 +13,7 @@ namespace ShakerService.ViewModel
         {
 
         }
-        public float Bias => Model.Bias;
-        public float OpenLoopDrive => Model.OpenLoopDrive;
+        public double Bias => Model.Bias;
+        public double OpenLoopDrive => Model.OpenLoopDrive;
     }
 }

+ 27 - 0
Shaker/ViewModel/ServiceDataCacheViewModel.cs

@@ -0,0 +1,27 @@
+using Shaker.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ShakerService.ViewModel
+{
+    internal class ServiceDataCacheViewModel:BaseServiceViewModel<IModel>
+    {
+        public float[] ReadedDataCache = new float[0];
+        public float[,] DataCache = new float[0, 0];
+        public float[] SensitivityValues = new float[0];
+        public uint ReadDataLength = 0;
+        public bool IsExit = false;
+        private ServiceDataCacheViewModel()
+        {
+
+        }
+        static ServiceDataCacheViewModel()
+        {
+
+        }
+        public static ServiceDataCacheViewModel Instance { get; } = new ServiceDataCacheViewModel();
+    }
+}

+ 6 - 4
Shaker/ViewModel/ServiceRandomConfigViewModel.cs

@@ -1,4 +1,5 @@
 using Shaker.Models;
+using ShakerService.Tools;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -9,21 +10,21 @@ namespace ShakerService.ViewModel
 {
     internal class ServiceRandomConfigViewModel:BaseServiceViewModel<RandomConfigModel>
     {
-        public float HanningWindowCompensationCoefficient => Model.HanningWindowCompensationCoefficient;
+        public double HanningWindowCompensationCoefficient => Model.HanningWindowCompensationCoefficient;
         public uint LinearAverage => Model.LinearAverage;
         public uint ExponentialAverage => Model.ExponentialAverage;
         public uint RandomSampleRate => Model.RandomSampleRate;
         public int MaxFrequency => (int)Model.MaxFrequency;
         public AccelerationSynthesisType SynthesisType => Model.SynthesisType;
-        public float MinFrequency => Model.MinFrequency;
+        public double MinFrequency => Model.MinFrequency;
         public uint SpectrumLines => (uint)Model.SpectrumLines;
-        public float Sigma =>Model.Sigma;
+        public double Sigma =>Model.Sigma;
         public ServiceRandomIdentifyViewModel Identify { get; } = new ServiceRandomIdentifyViewModel();
         public List<ServiceRandomSpectrumItemViewModel> SpectrumItems { get; } = new List<ServiceRandomSpectrumItemViewModel>();
         public List<ServiceRandomPlanItemViewModel> PlanItems { get; } = new List<ServiceRandomPlanItemViewModel>();
         public uint StopLins =>Model.StopLins;
         public uint WarnLines =>Model.WarnLines;
-        public float StopRMS =>Model.StopRMS;
+        public double StopRMS =>Model.StopRMS;
         private ServiceRandomConfigViewModel()
         {
             Communication.Instance.DbConnection.CreateTable<RandomConfigModel>();
@@ -41,6 +42,7 @@ namespace ShakerService.ViewModel
                 UpModel(args.Data);
                 SaveData();
             });
+            Log.Default.Info("初始化随机参数");
         }
         static ServiceRandomConfigViewModel()
         {

+ 6 - 6
Shaker/ViewModel/ServiceRandomSpectrumItemViewModel.cs

@@ -11,12 +11,12 @@ namespace ShakerService.ViewModel
         public ServiceRandomSpectrumItemViewModel(RandomSpectrumItemModel model):base(model)
         {
         }
-        public float Frequency => Model.Frequency;
+        public double Frequency => Model.Frequency;
         public RandomValueType ValueType => Model.ValueType;
-        public float Value =>Model.Value;
-        public float UpStop =>Model.UpStop;
-        public float UpWarn =>Model.UpWarn;
-        public float DownStop =>Model.DownStop;
-        public float DownWarn =>Model.DownWarn;
+        public double Value =>Model.Value;
+        public double UpStop =>Model.UpStop;
+        public double UpWarn =>Model.UpWarn;
+        public double DownStop =>Model.DownStop;
+        public double DownWarn =>Model.DownWarn;
     }
 }

+ 34 - 13
Shaker/ViewModel/ServiceShakerConfigViewModel.cs

@@ -1,4 +1,5 @@
 using Shaker.Models;
+using ShakerService.Tools;
 using System;
 using System.Collections.Generic;
 using System.Diagnostics.Metrics;
@@ -12,7 +13,7 @@ namespace ShakerService.ViewModel
     internal class ServiceShakerConfigViewModel:BaseServiceViewModel<Shaker.Models.ShakerConfigModel>
     {
         public AccelerationSynthesisType SynthesisType { get => Model.SynthesisType; }
-        public float OutSignalGain { get => Model.OutSignalGain;  }
+        public double OutSignalGain { get => Model.OutSignalGain;  }
 
         public uint MaxRiseCount => Model.MaxRiseCount;
         public uint MaxZeroChangedCount => Model.MaxZeroChangedCount;
@@ -22,25 +23,25 @@ namespace ShakerService.ViewModel
         public uint MaxAdjustCount => Model.MaxAdjustCount;
         public uint MaxFallCount => Model.MaxFallCount;
         public uint StartCount => Model.StartCount;
-        public float InitialLocation { get => Model.InitialLocation; }
+        public double InitialLocation { get => Model.InitialLocation; }
         public uint SampleRate => Model.SampleRate;
         public uint FPGAClock => Model.FPGAClock;
         public int ChannelCount => Model.AnalogSignalConfigs.Count;
-        public float MaxFrequency { get => Model.MaxFrequency; }
-        public float MinFrequency { get => Model.MinFrequency;}
+        public double MaxFrequency { get => Model.MaxFrequency; }
+        public double MinFrequency { get => Model.MinFrequency;}
 
-        public float MaxOutInput { get => Model.MaxOutInput;  }
-        public float MaxAcceleration { get => Model.MaxAcceleration;  }
-        public float MaxDisplacement { get => Model.MaxDisplacement;  }
-        public float MaxDriver { get => Model.MaxDriver;}
-        public float MaxJitterAcceleration { get => Model.MaxJitterAcceleration; }
-        public float MaxJitterDisplacement { get => Model.MaxJitterDisplacement; }
-        public float MaxVelocity { get => Model.MaxVelocity; }
+        public double MaxOutInput { get => Model.MaxOutInput;  }
+        public double MaxAcceleration { get => Model.MaxAcceleration;  }
+        public double MaxDisplacement { get => Model.MaxDisplacement;  }
+        public double MaxDriver { get => Model.MaxDriver;}
+        public double MaxJitterAcceleration { get => Model.MaxJitterAcceleration; }
+        public double MaxJitterDisplacement { get => Model.MaxJitterDisplacement; }
+        public double MaxVelocity { get => Model.MaxVelocity; }
         public int AccelerationSensorCount => Model.AccelerationConfigs.Count;
         public List<ServiceAnalogSignalConfigViewModel> AnalogSignals { get; } = new List<ServiceAnalogSignalConfigViewModel>();
         public List<ServiceAccelerationConfigViewModel> Accelerations { get; } = new List<ServiceAccelerationConfigViewModel>();
-        public float DisplacementSensitivity { get => Model.DisplacementSensitivity; }
-        public float AccelerationSensitivity => Accelerations.Count > 0 ? Accelerations[0].Sensitivity : 1;
+        public double DisplacementSensitivity { get => Model.DisplacementSensitivity; }
+        public double AccelerationSensitivity => Accelerations.Count > 0 ? Accelerations[0].Sensitivity : 1;
         private ServiceShakerConfigViewModel()
         {
             Communication.Instance.DbConnection.CreateTable<Shaker.Models.ShakerConfigModel>();
@@ -63,11 +64,13 @@ namespace ShakerService.ViewModel
             SaveData();
             Communication.Instance.Context.GetEvent<Shaker.Models.ShakerConfigModel>().Subscrip((sender, args) =>
             {
+                Log.Default.Info($"修改{nameof(ShakerConfigModel)}");
                 UpModel(args.Data);
                 SetFpga();
                 ServiceSweepConfigViewModel.Instance.SetFpga();
                 SaveData();
             });
+            Log.Default.Info("初始化振动台参数");
         }
         public override void SetFpga()
         {
@@ -102,11 +105,15 @@ namespace ShakerService.ViewModel
                 ShakerFpga.Instance.StartCount.Value = StartCount;
                 ShakerFpga.Instance.LoopRate.Value = FPGAClock / SampleRate;
                 ShakerFpga.Instance.SynthesisType.Value = (ushort)SynthesisType;
+                ShakerFpga.Instance.Weight.Value = new double[] { 1, 0 };
                 ShakerFpga.Instance.OutSignalGain.Value = OutSignalGain;
                 ShakerFpga.Instance.MaxAdjustCount.Value = MaxAdjustCount;
                 ShakerFpga.Instance.StartCount.Value = StartCount;
                 ShakerFpga.Instance.MaxJitterAcceleration.Value = Shaker.Models.Tools.Tools.QuantitiesToVoltage(MaxJitterAcceleration, AccelerationSensitivity);
                 ShakerFpga.Instance.MaxJitterDisplacement.Value = Shaker.Models.Tools.Tools.QuantitiesToVoltage(MaxJitterDisplacement, DisplacementSensitivity);
+                ShakerFpga.Instance.DisplacementI.Value = ServiceShakerControlViewModel.Instance.DisplacementI / SampleRate;
+                ShakerFpga.Instance.FlutterFrequency.Value = ServiceShakerControlViewModel.Instance.FlutterFrequency * 2 / SampleRate;
+
             }
             catch
             {
@@ -147,6 +154,20 @@ namespace ShakerService.ViewModel
             {
                 Accelerations.AddRange(model.AccelerationConfigs.Select(x => new ServiceAccelerationConfigViewModel(x)));
             }
+            Enumerable.Range(0, ServiceConfigViewModel.Instance.AnalogCount)
+                .Where(x => AnalogSignals[x].AnalogType == AnalogType.Displacement)
+                .ToList()
+                .ForEach(x =>
+                {
+                    ServiceDataCacheViewModel.Instance.SensitivityValues[x] = 1000f / (float)DisplacementSensitivity;
+                });
+            Enumerable.Range(0, ServiceConfigViewModel.Instance.AnalogCount)
+                .Where(x => AnalogSignals[x].AnalogType == AnalogType.Acceleration)
+                .ToList()
+                .ForEach(x => 
+                {
+                    ServiceDataCacheViewModel.Instance.SensitivityValues[x] = 1000f / (float)AccelerationSensitivity;
+                });
         }
         private protected override void SaveData()
         {

+ 11 - 5
Shaker/ViewModel/ServiceShakerControlViewModel.cs

@@ -1,4 +1,5 @@
 using Shaker.Models;
+using ShakerService.Tools;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -16,8 +17,8 @@ namespace ShakerService.ViewModel
         public float MaxDisplacementVoltage=>Model.MaxDisplacementVoltage;
         public float MinDisplacementVoltage =>Model.MinDisplacementVoltage;
         public Polarity ValvePolarity =>Model.ValvePolarity;
-        public bool SelfLoop=>Model.SelfLoop;
-        public bool Debug =>Model.Debug;
+        public bool SelfLoop { get => Model.SelfLoop; set => Model.SelfLoop = value; }
+        public bool Debug { get =>Model.Debug;set=>Model.Debug = value; }
         public float DisplacementP =>Model.DisplacementP;
         public float DisplacementI =>Model.DisplacementI;
         public float FlutterFrequency =>Model.FlutterFrequency;
@@ -29,12 +30,15 @@ namespace ShakerService.ViewModel
         public float DisplacementBias => Model.DisplacementBias;
         public bool OilStopped => Model.OilStopped;
         public bool DisplacementOpenLoop => Model.DisplacementOpenLoop;
-        public bool OutSignal => Model.OutSignal;
+        public bool OutSignal {get=> Model.OutSignal;set=>Model.OutSignal = value; }
         private ServiceShakerControlViewModel()
         {
             Communication.Instance.DbConnection.CreateTable<ShakerControlModel>();
             var model = Communication.Instance.DbConnection.Query<ShakerControlModel>($"select * from {nameof(ShakerControlModel)} LIMIT 1")?.FirstOrDefault() ?? new ShakerControlModel();
             model.PageType = MainPageType.StartPage;
+            model.Debug = false;
+            model.SelfLoop = false;
+            model.OutSignal = false;
             Communication.Instance.DbConnection.CreateTable<ValveConfigItemModel>(tableName: nameof(ValveConfig));
             model.ValveConfig = Communication.Instance.DbConnection.Query<ValveConfigItemModel>($"select * from {nameof(ValveConfig)}") ?? new List<ValveConfigItemModel>();
             Communication.Instance.DbConnection.CreateTable<SweepControlItemModel>(tableName:nameof(SweepControlItems));
@@ -49,10 +53,12 @@ namespace ShakerService.ViewModel
             SaveData();
             Communication.Instance.Context.GetEvent<ShakerControlModel>().Subscrip((sender, args) =>
             {
+                Log.Default.Info($"修改{nameof(ShakerControlModel)}");
                 UpModel(args.Data);
                 SetFpga();
                 SaveData();
             });
+            Log.Default.Info("初始化控制参数");
         }
         static ServiceShakerControlViewModel()
         {
@@ -68,12 +74,12 @@ namespace ShakerService.ViewModel
                 ShakerFpga.Instance.DisplacementOpenLoop.Value = DisplacementOpenLoop;
                 ShakerFpga.Instance.OutSignal.Value = OutSignal;
                 ShakerFpga.Instance.DisplacementBias.Value = DisplacementBias;
-                ShakerFpga.Instance.DisplacementI.Value = DisplacementI;
+                ShakerFpga.Instance.DisplacementI.Value = DisplacementI / ServiceShakerConfigViewModel.Instance.SampleRate;
                 ShakerFpga.Instance.DisplacementP.Value = DisplacementP;
                 ShakerFpga.Instance.SelfLoop.Value = SelfLoop;
                 ShakerFpga.Instance.Debug.Value = Debug;
                 ShakerFpga.Instance.FlutterAmpt.Value = FlutterAmpt;
-                ShakerFpga.Instance.FlutterFrequency.Value = FlutterFrequency;
+                ShakerFpga.Instance.FlutterFrequency.Value = FlutterFrequency * 2 / ServiceShakerConfigViewModel.Instance.SampleRate;
                 ShakerFpga.Instance.ValveBias.Value = ValveConfig.Select(x => x.Bias).ToArray();
                 ShakerFpga.Instance.OpenLoopDisplacement.Value = ValveConfig.Select(x => x.OpenLoopDrive).ToArray();
             }

+ 1 - 2
Shaker/ViewModel/ServiceShakerStatusViewModel.cs

@@ -19,7 +19,6 @@ namespace ShakerService.ViewModel
         }
         public void ReadFpgaData()
         {
-            _NeedSendData = false;
             RTStatus = (RTStatus)ShakerFpga.Instance.RTStatus.Value;
             var val = ShakerFpga.Instance.Rised.Value;
             if(val!=IsTableRised)
@@ -57,7 +56,7 @@ namespace ShakerService.ViewModel
             ZeroChangedCount = ShakerFpga.Instance.ZeroChangedIndex.Value;
             WarnCode = ShakerFpga.Instance.WarnCode.Value;
             ErrorCode = ShakerFpga.Instance.ErrorCode.Value;
-            if(_NeedSendData) SendData();
+            SendData();
         }
         public static ServiceShakerStatusViewModel Instance { get; } = new ServiceShakerStatusViewModel();
         public RTStatus RTStatus {get=>Model.RTStatus; set=>SetProperty(ref Model.RTStatus , value); }

+ 10 - 6
Shaker/ViewModel/ServiceSineDataViewModel.cs

@@ -5,24 +5,28 @@ namespace ShakerService.ViewModel
     internal class ServiceSineDataViewModel:BaseServiceViewModel<SineDataModel>,IData
     {
         public uint SweepIndex {get=>Model.SweepIndex; set=>SetProperty(ref Model.SweepIndex , value); }
-        public float TotalTime { get => Model.TotalTime; set => SetProperty(ref Model.TotalTime, value); }
-        public float RunTime { get => Model.RunTime; set => SetProperty(ref Model.RunTime, value); }
-        public float CurrentFrequency { get => Model.CurrentFrequency; set => SetProperty(ref Model.CurrentFrequency, value); }
-        public float CurrentAcceleration { get => Model.CurrentAcceleration; set => SetProperty(ref Model.CurrentAcceleration, value); }
+        public double TotalTime { get => Model.TotalTime; set => SetProperty(ref Model.TotalTime, value); }
+        public double RunTime { get => Model.RunTime; set => SetProperty(ref Model.RunTime, value); }
+        public double CurrentFrequency { get => Model.CurrentFrequency; set => SetProperty(ref Model.CurrentFrequency, value); }
+        public double CurrentAcceleration { get => Model.CurrentAcceleration; set => SetProperty(ref Model.CurrentAcceleration, value); }
         public SweepDirection SweepDirection { get => Model.SweepDirection; set => SetProperty(ref Model.SweepDirection, value); }
         public SweepStep SweepStep { get => Model.SweepStep; set => SetProperty(ref Model.SweepStep, value); }
         public MainPageType MainPageType => Model.MainPageType;
 
         public void ReadFpgaData()
         {
-            _NeedSendData = false;
             SweepIndex = ShakerFpga.Instance.SweepIndex.Value;
             CurrentFrequency = ShakerFpga.Instance.CurrentFrequency.Value;
             RunTime = ShakerFpga.Instance.FixedFrequencyTime.Value / (float)ServiceShakerConfigViewModel.Instance.SampleRate;
             SweepStep = (SweepStep)ShakerFpga.Instance.SweepStep.Value;
             SweepDirection = ShakerFpga.Instance.CurrentSweepDirection.Value ? SweepDirection.Down : SweepDirection.Up;
-            if(_NeedSendData) SendData();
+            SendData();
         }
+        public override string ToString()
+        {
+            return $"{CurrentFrequency}Hz,{CurrentAcceleration}g,{SweepDirection},{SweepStep}";
+        }
+
     }
 
     internal interface IData

+ 28 - 23
Shaker/ViewModel/ServiceSweepConfigViewModel.cs

@@ -1,5 +1,6 @@
 using Shaker.Models;
 using Shaker.Models.Tools;
+using ShakerService.Tools;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -32,10 +33,12 @@ namespace ShakerService.ViewModel
             SaveData();
             Communication.Instance.Context.GetEvent<SweepConfigModel>().Subscrip((sender, args) =>
             {
+                Log.Default.Info($"修改{nameof(SweepConfigModel)}");
                 UpModel(args.Data);
                 SetFpga();
                 SaveData();
             });
+            Log.Default.Info("初始化扫频参数");
         }
 
         public override void SetFpga()
@@ -46,10 +49,12 @@ namespace ShakerService.ViewModel
                 ShakerFpga.Instance.SweepCount.Value = SweepCount;
                 ShakerFpga.Instance.SweepDown.Value = SweepDirection == SweepDirection.Down;
                 ShakerFpga.Instance.Linear.Value = SweepType == SweepType.Linear;
-                float startfreq = SweepStartFrequency;
-                float startacc = Model.CalcAmpt(startfreq);
-                float startdisp = Shaker.Models.Tools.Tools.AccelerationToDisplacement(startacc, startfreq) * SweepStartLevel;
-                float startdispV = Shaker.Models.Tools.Tools.QuantitiesToVoltage(startdisp, ServiceShakerConfigViewModel.Instance.DisplacementSensitivity);
+                ShakerFpga.Instance.SynthesisType.Value = (byte)AccelerationSynthesisType.Synthesis;
+                ShakerFpga.Instance.Weight.Value = SelectChannel == 0 ? new double[] { 1,0} : new double[] { 0,1};
+                double startfreq = SweepStartFrequency;
+                double startacc = Model.CalcAmpt(startfreq);
+                double startdisp = Shaker.Models.Tools.Tools.AccelerationToDisplacement(startacc, startfreq) * SweepStartLevel;
+                double startdispV = Shaker.Models.Tools.Tools.QuantitiesToVoltage(startdisp, ServiceShakerConfigViewModel.Instance.DisplacementSensitivity);
                 ShakerFpga.Instance.InitialDisplacement.Value = startdispV;
                 ShakerFpga.Instance.FixedFrequency.Value = SignalType == SignalType.Fixed;
                 SweepData.TotalTime = Model.OnceSweepTime * Model.SweepCount;
@@ -57,7 +62,7 @@ namespace ShakerService.ViewModel
                 ShakerFpga.Instance.MaxFrequency.Value = Model.EndFrequency;
                 ShakerFpga.Instance.AdjustmentCoefficient.Value = 1;
                 ShakerFpga.Instance.TargetAcceleration.Value = Shaker.Models.Tools.Tools.QuantitiesToVoltage(startacc * SweepLevelGain, ServiceShakerConfigViewModel.Instance.AccelerationSensitivity);
-                ShakerFpga.Instance.MaxFixedFrequencyTime.Value = (ulong)SweepData.TotalTime;
+                ShakerFpga.Instance.MaxFixedFrequencyTime.Value = (ulong)(SweepData.TotalTime*ServiceShakerConfigViewModel.Instance.SampleRate);
                 if (ServiceShakerControlViewModel.Instance.SweepControlItems.Count > 0)
                 {
                     var item = ServiceShakerControlViewModel.Instance.SweepControlItems.FirstOrDefault(x => startfreq <= x.Frequency) ?? ServiceShakerControlViewModel.Instance.SweepControlItems.Last();
@@ -76,11 +81,11 @@ namespace ShakerService.ViewModel
                 {
                     ShakerFpga.Instance.SensitivityAdjustmentCoefficient.Value = 1;
                 }
-                float value = 0;
-                float upstop = 0;
-                float upwarn = 0;
-                float downstop = 0;
-                float downwarn = 0;
+                double value = 0;
+                double upstop = 0;
+                double upwarn = 0;
+                double downstop = 0;
+                double downwarn = 0;
                 ServiceSweepConfigViewModel.Instance.Model.CalcAmpt(startfreq, ref value, ref upstop, ref upwarn, ref downstop, ref downwarn);
                 ShakerFpga.Instance.LowerStop.Value = Shaker.Models.Tools.Tools.QuantitiesToVoltage(downstop, ServiceShakerConfigViewModel.Instance.AccelerationSensitivity);
                 ShakerFpga.Instance.LowerWarn.Value = Shaker.Models.Tools.Tools.QuantitiesToVoltage(downwarn, ServiceShakerConfigViewModel.Instance.AccelerationSensitivity);
@@ -96,25 +101,25 @@ namespace ShakerService.ViewModel
         { 
 
         }
-        public float SweepStartFrequency=> SignalType == SignalType.Fixed ? StartFrequency : (SweepDirection == SweepDirection.Up ? StartFrequency : EndFrequency);
+        public double SweepStartFrequency => SignalType == SignalType.Fixed ? StartFrequency : (SweepDirection == SweepDirection.Up ? StartFrequency : EndFrequency);
         public static ServiceSweepConfigViewModel Instance { get; } = new ServiceSweepConfigViewModel();
         public uint SweepCount => Model.SweepCount;
         public SweepType SweepType => Model.SweepType;
         public SweepDirection SweepDirection => Model.SweepDirection;
         public SignalType SignalType => Model.SignalType;
-        public float SweepSpeed => Model.SweepSpeed;
-        public float StartFrequency => Model.StartFrequency;
-        public float EndFrequency => Model.EndFrequency;
-        public float SweepStartLevel=>Model.SweepStartLevel;
-        public float CrossoverPoint => Model.CrossoverPoint; 
-        public float SweepLevelGain =>Model.SweepLevelGain;
-        public float LowFrequencyMinCorrect =>Model.LowFrequencyMinCorrect;
-        public float LowFrequencyMaxCorrect =>Model.LowFrequencyMaxCorrect;
-        public float HigthFrequencyMinCorrect =>Model.HigthFrequencyMinCorrect;
-        public float HigthFrequencyMaxCorrect =>Model.HigthFrequencyMaxCorrect;
+        public double SweepSpeed => Model.SweepSpeed;
+        public double StartFrequency => Model.StartFrequency;
+        public double EndFrequency => Model.EndFrequency;
+        public double SweepStartLevel =>Model.SweepStartLevel;
+        public double CrossoverPoint => Model.CrossoverPoint; 
+        public double SweepLevelGain =>Model.SweepLevelGain;
+        public double LowFrequencyMinCorrect =>Model.LowFrequencyMinCorrect;
+        public double LowFrequencyMaxCorrect =>Model.LowFrequencyMaxCorrect;
+        public double HigthFrequencyMinCorrect =>Model.HigthFrequencyMinCorrect;
+        public double HigthFrequencyMaxCorrect =>Model.HigthFrequencyMaxCorrect;
         public int SelectChannel =>Model.SelectChannel;
-        public float LowFreq => Model.LowFreq;
-        public float HighFreq => Model.HighFreq;
+        public double LowFreq => Model.LowFreq;
+        public double HighFreq => Model.HighFreq;
         public List<ServiceSweepItemViewModel> SweepItems { get; } = new List<ServiceSweepItemViewModel>();
         public override void UpModel(SweepConfigModel model)
         {

+ 6 - 6
Shaker/ViewModel/ServiceSweepItemViewModel.cs

@@ -10,11 +10,11 @@ namespace ShakerService.ViewModel
         {
         }
         public SweepValueType SweepValueType =>Model.SweepValueType;
-        public float Value =>Model.Value;
-        public float Frequency =>Model.Frequency;
-        public float UpStop =>Model.UpStop;
-        public float UpWarn =>Model.UpWarn;
-        public float DownStop =>Model.DownStop;
-        public float DownWarn =>Model.DownWarn;
+        public double Value =>Model.Value;
+        public double Frequency =>Model.Frequency;
+        public double UpStop =>Model.UpStop;
+        public double UpWarn =>Model.UpWarn;
+        public double DownStop =>Model.DownStop;
+        public double DownWarn =>Model.DownWarn;
     }
 }

+ 0 - 8
ShakerControl.sln

@@ -9,8 +9,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zh-CN", "Language\Zh-CN\Zh-
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILanguage", "Language\ILanguage\ILanguage.csproj", "{32D94A9C-0567-4C4D-997C-EC494D151009}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BaseCpuFxpConvert", "Calc\BaseCpuFxpConvert\BaseCpuFxpConvert.csproj", "{C5FE9372-20CC-4B70-B25B-B0C788F118B7}"
-EndProject
 Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Calc.Common", "Calc\FxpConvert.Common\Calc.Common.shproj", "{B38D0878-21D0-463D-BE35-913FF3803CA3}"
 EndProject
 Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "NIFPGA", "NIFPGA\NIFPGA.shproj", "{0FC2485C-345E-41BF-BBC7-876E25AF92F4}"
@@ -127,10 +125,6 @@ Global
 		{32D94A9C-0567-4C4D-997C-EC494D151009}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{32D94A9C-0567-4C4D-997C-EC494D151009}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{32D94A9C-0567-4C4D-997C-EC494D151009}.Release|Any CPU.Build.0 = Release|Any CPU
-		{C5FE9372-20CC-4B70-B25B-B0C788F118B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{C5FE9372-20CC-4B70-B25B-B0C788F118B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{C5FE9372-20CC-4B70-B25B-B0C788F118B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{C5FE9372-20CC-4B70-B25B-B0C788F118B7}.Release|Any CPU.Build.0 = Release|Any CPU
 		{32592E1E-E305-4241-A454-D19C56C158F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{32592E1E-E305-4241-A454-D19C56C158F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{32592E1E-E305-4241-A454-D19C56C158F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -258,7 +252,6 @@ Global
 	GlobalSection(NestedProjects) = preSolution
 		{BD76D4F9-93BD-4FEB-90F5-DFEFDD890D8D} = {3FE3DCDE-811F-438E-9FEA-771D5A9BBF5B}
 		{32D94A9C-0567-4C4D-997C-EC494D151009} = {3FE3DCDE-811F-438E-9FEA-771D5A9BBF5B}
-		{C5FE9372-20CC-4B70-B25B-B0C788F118B7} = {77E3D4F2-F63C-4E2F-899E-CA5268B6FB53}
 		{B38D0878-21D0-463D-BE35-913FF3803CA3} = {77E3D4F2-F63C-4E2F-899E-CA5268B6FB53}
 		{E82E51E4-0CA1-4B1F-A2A7-B3B9EB22B96B} = {77E3D4F2-F63C-4E2F-899E-CA5268B6FB53}
 		{3910EF8A-CD3E-4EDE-B2E5-16892F308121} = {5014ECCD-852C-4054-83FA-74E2D6A66589}
@@ -321,7 +314,6 @@ Global
 		Communication\ActiveMQ\EasyMQ.Common\EasyMQ.Common.projitems*{b06e5c74-8db5-4e29-996b-b1b5ef43b6de}*SharedItemsImports = 13
 		Calc\FxpConvert.Common\Calc.Common.projitems*{b38d0878-21d0-463d-be35-913ff3803ca3}*SharedItemsImports = 13
 		OxyPlot\OxyPlot\OxyPlot.projitems*{c0c33a23-e2ba-4f04-83b3-2d512db0a46c}*SharedItemsImports = 13
-		Calc\FxpConvert.Common\Calc.Common.projitems*{c5fe9372-20cc-4b70-b25b-b0c788f118b7}*SharedItemsImports = 5
 		EventBroker.Common\EventBroker.Common.projitems*{e2eb40cf-1365-42ed-9bed-469c5ef67a94}*SharedItemsImports = 5
 		Calc\FxpConvert.Common\Calc.Common.projitems*{e82e51e4-0ca1-4b1f-a2a7-b3b9eb22b96b}*SharedItemsImports = 5
 		OxyPlot\OxyPlot\OxyPlot.projitems*{f1f157cd-990c-48a9-8ec2-c0d5dee8d8a4}*SharedItemsImports = 5