using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Globalization; using System.IO; using System.IO.Ports; using System.Linq; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Controls.Primitives; using System.Windows.Threading; using Correlator.DataService; using Correlator.Events; using Correlator.Model; using Correlator.SensorHubTag; using Correlator.Util; using Correlator.Views; using HandyControl.Controls; using MathWorks.MATLAB.NET.Arrays; using Newtonsoft.Json; using Prism.Commands; using Prism.Events; using Prism.Mvvm; using Prism.Services.Dialogs; using ComboBox = System.Windows.Controls.ComboBox; namespace Correlator.ViewModels { public class MainWindowViewModel : BindableBase { #region DispatcherTimer private readonly DispatcherTimer _checkSerialPortTimer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 7) }; private readonly DispatcherTimer _timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) }; private readonly DispatcherTimer _batteryTimer = new DispatcherTimer { Interval = TimeSpan.FromMinutes(5) }; //运行时间Timer private readonly DispatcherTimer _runningTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) }; //自动截屏倒计时 private readonly DispatcherTimer _snapShotTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(3) }; //指令记录刷新计时器 private readonly DispatcherTimer _commandTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1) }; #endregion #region 变量 private readonly IEventAggregator _eventAggregator; private readonly IApplicationDataService _dataService; private readonly IDialogService _dialogService; private readonly ISerialPortService _serialPortService; private readonly IAudioService _audioService; private readonly ICommandService _commandService; private readonly BackgroundWorker _backgroundWorker; private readonly string _today; private readonly string _week; private MainWindow _mainWindow; private string _locateDataDir; private int _locateTimes; private string _snapShotPath = string.Empty; private ParamConfigModel _paramConfig; //计算时间 private int _runningSeconds; //Matlab算法 private static readonly Lazy<CorrelatorSingle.Correlator> LazyCorrelator = new Lazy<CorrelatorSingle.Correlator>(() => new CorrelatorSingle.Correlator()); #endregion #region VM属性 private string _currentTime; public string CurrentTime { get => _currentTime; private set { _currentTime = value; RaisePropertyChanged(); } } /// <summary> /// 红色发射机信号强度0-5 /// </summary> private int _redTransmitterSignal; public int RedTransmitterSignal { get => _redTransmitterSignal; private set { _redTransmitterSignal = value; RaisePropertyChanged(); } } /// <summary> /// 蓝色发射机信号强度0-5 /// </summary> private int _blueTransmitterSignal; public int BlueTransmitterSignal { get => _blueTransmitterSignal; private set { _blueTransmitterSignal = value; RaisePropertyChanged(); } } /// <summary> /// 绑定干扰频段值 /// </summary> private string _interferenceFrequency = "无"; public string InterferenceFrequency { get => _interferenceFrequency; private set { _interferenceFrequency = value; RaisePropertyChanged(); } } /// <summary> /// 绑定过信噪比 /// </summary> private string _snr = "无"; public string Snr { get => _snr; private set { _snr = value; RaisePropertyChanged(); } } /// <summary> /// 绑定过滤器值 /// </summary> private string _filterValue = " ~ Hz"; public string FilterValue { get => _filterValue; private set { _filterValue = value; RaisePropertyChanged(); } } /// <summary> /// 绑定声速值 /// </summary> private string _soundSpeed = "0"; public string SoundSpeed { get => _soundSpeed; private set { _soundSpeed = value; RaisePropertyChanged(); } } /// <summary> /// 绑定采样率 /// </summary> private int _soundSampleRate = 7500; public int SoundSampleRate { get => _soundSampleRate; private set { _soundSampleRate = value; RaisePropertyChanged(); } } /// <summary> /// 红色发射机是否故障 /// </summary> private bool _redTransmitterState; public bool RedTransmitterState { get => _redTransmitterState; set { _redTransmitterState = value; RaisePropertyChanged(); } } /// <summary> /// 蓝色发射机是否故障 /// </summary> private bool _blueTransmitterState; public bool BlueTransmitterState { get => _blueTransmitterState; private set { _blueTransmitterState = value; RaisePropertyChanged(); } } /// <summary> /// 红色发射机距离 /// </summary> private double _redTransmitterDistance; public double RedTransmitterDistance { get => _redTransmitterDistance; private set { _redTransmitterDistance = value; RaisePropertyChanged(); } } /// <summary> /// 蓝色发射机距离 /// </summary> private double _blueTransmitterDistance; public double BlueTransmitterDistance { get => _blueTransmitterDistance; private set { _blueTransmitterDistance = value; RaisePropertyChanged(); } } /// <summary> /// 红色发射机电量 0-100 /// </summary> private int _redTransmitterBattery; public int RedTransmitterBattery { get => _redTransmitterBattery; set { _redTransmitterBattery = value; RaisePropertyChanged(); } } /// <summary> /// 蓝色发射机电量 0-100 /// </summary> private int _blueTransmitterBattery; public int BlueTransmitterBattery { get => _blueTransmitterBattery; set { _blueTransmitterBattery = value; RaisePropertyChanged(); } } /// <summary> /// 电脑电量 0-100 /// </summary> private int _computerBattery; public int ComputerBattery { get => _computerBattery; set { _computerBattery = value; RaisePropertyChanged(); } } /// <summary> /// 绑定经过了值 /// </summary> private string _elapseTime = "0"; public string ElapseTime { get => _elapseTime; private set { _elapseTime = value; RaisePropertyChanged(); } } private string _connectColorBrush = "LightGray"; public string ConnectColorBrush { get => _connectColorBrush; private set { _connectColorBrush = value; RaisePropertyChanged(); } } private ObservableCollection<string> _pipeMaterialsArray; public ObservableCollection<string> PipeMaterialsArray { get => _pipeMaterialsArray; set { _pipeMaterialsArray = value; RaisePropertyChanged(); } } private string _materialName = string.Empty; public string MaterialName { get => _materialName; set { _materialName = value; RaisePropertyChanged(); } } private string _pipeDiameter = string.Empty; public string PipeDiameter { get => _pipeDiameter; set { _pipeDiameter = value; RaisePropertyChanged(); } } private string _pipeLength = string.Empty; public string PipeLength { get => _pipeLength; set { _pipeLength = value; RaisePropertyChanged(); } } private string _frequencyInterval = "100 ~ 3000Hz"; public string FrequencyInterval { get => _frequencyInterval; private set { _frequencyInterval = value; RaisePropertyChanged(); } } private string _lowFrequency = string.Empty; public string LowFrequency { get => _lowFrequency; set { _lowFrequency = value; RaisePropertyChanged(); } } private string _highFrequency = string.Empty; public string HighFrequency { get => _highFrequency; set { _highFrequency = value; RaisePropertyChanged(); } } //是否已开始采集或者计算数据 private bool _startButtonIsEnabled; public bool StartButtonEnabled { get => _startButtonIsEnabled; private set { _startButtonIsEnabled = value; RaisePropertyChanged(); } } private CorrelatorDataModel _correlatorData = new CorrelatorDataModel(); public CorrelatorDataModel CorrelatorData { get => _correlatorData; set { _correlatorData = value; RaisePropertyChanged(); } } private CommandModel _lastCommand; public CommandModel LastCommand { get => _lastCommand; set { _lastCommand = value; RaisePropertyChanged(); } } #endregion #region PC电量状态 [DllImport("kernel32.dll", EntryPoint = "GetSystemPowerStatus")] private static extern void GetSystemPowerStatus(ref SystemConfig.SystemPowerStatus lpSystemPowerStatus); #endregion #region DelegateCommand public DelegateCommand<MainWindow> WindowLoadedCommand { set; get; } public DelegateCommand CloseWindowCommand { private set; get; } public DelegateCommand<Popup> OpenFolderCommand { private set; get; } public DelegateCommand<Popup> OpenImageFileCommand { private set; get; } public DelegateCommand<Popup> OpenAudioFileCommand { private set; get; } public DelegateCommand OpenListenAudioCommand { private set; get; } public DelegateCommand ShowWaveCommand { private set; get; } public DelegateCommand OpenNumericKeypadCommand { private set; get; } public DelegateCommand<ComboBox> PipeItemSelectedCommand { set; get; } public DelegateCommand DetectNoiseCommand { private set; get; } public DelegateCommand<Popup> ExtensionsCommand { private set; get; } public DelegateCommand<Popup> SoundSampleRateCommand { private set; get; } public DelegateCommand<Popup> SoundSpeedCommand { private set; get; } public DelegateCommand<Popup> ImportDataCommand { private set; get; } public DelegateCommand<Popup> HelpCenterCommand { private set; get; } public DelegateCommand<Popup> ShowLogCommand { private set; get; } public DelegateCommand<Popup> ShowApplicationInfoCommand { private set; get; } public DelegateCommand SaveAudioCommand { private set; get; } public DelegateCommand ResetParamCommand { private set; get; } public DelegateCommand SnapShotCommand { private set; get; } public DelegateCommand StartCollectDataCommand { private set; get; } #endregion public MainWindowViewModel(IEventAggregator eventAggregator, IApplicationDataService dataService, IDialogService dialogService, ISerialPortService serialPortService, IAudioService audioService, ICommandService commandService) { _eventAggregator = eventAggregator; _dataService = dataService; _dialogService = dialogService; _serialPortService = serialPortService; _audioService = audioService; _commandService = commandService; // 算法计算后台任务 _backgroundWorker = new BackgroundWorker(); _backgroundWorker.WorkerReportsProgress = true; _backgroundWorker.WorkerSupportsCancellation = true; _backgroundWorker.DoWork += Worker_OnDoWork; _backgroundWorker.ProgressChanged += Worker_OnProgressChanged; _backgroundWorker.RunWorkerCompleted += Worker_OnRunWorkerCompleted; _pipeMaterialsArray = new ObservableCollection<string>(); var pipeMaterials = dataService.GetPipeMaterial(); foreach (var material in pipeMaterials) { PipeMaterialsArray.Add(material.ChineseMaterial); } //获取当前日期,星期 _today = DateTime.Now.ToString("yyyy年MM月dd日"); _week = DateTime.Now.ToString("dddd", new CultureInfo("zh-cn")); RegisterMessage(); TimerTick(); InitDelegateCommand(); } /// <summary> /// 消息监听注册 /// </summary> private void RegisterMessage() { _eventAggregator.GetEvent<RedSensorEvent>().Subscribe(delegate(DevStatus dev) { "MainWindowViewModel".WriteLog("Red Sensor收到消息:" + JsonConvert.SerializeObject(dev)); //新协议不计算实际信号 RedTransmitterBattery = Convert.ToInt32(dev.Cell); RedTransmitterSignal = 5; RedTransmitterState = true; RuntimeCache.RedSensorIsEnable = true; }); _eventAggregator.GetEvent<BlueSensorEvent>().Subscribe(delegate(DevStatus dev) { "MainWindowViewModel".WriteLog("Blue Sensor收到消息:" + JsonConvert.SerializeObject(dev)); //新协议不计算实际信号 BlueTransmitterBattery = Convert.ToInt32(dev.Cell); BlueTransmitterSignal = 5; BlueTransmitterState = true; RuntimeCache.BlueSensorIsEnable = true; //因为红色先收到信号,所以只需要等到蓝色也收到信号即可 StartButtonEnabled = true; }); //加速度计 _eventAggregator.GetEvent<StartCalculateEvent>().Subscribe(StartCalculateData); //水听器 _eventAggregator.GetEvent<ShowCheckResponseEvent>().Subscribe(delegate { _dialogService.Show("CheckResponseDialog", null, delegate(IDialogResult result) { if (result.Result == ButtonResult.Cancel) { ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "数据未校验,无法进行计算"); return; } if (result.Result == ButtonResult.Abort) { ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "数据校验被终止,无法进行计算"); return; } if (result.Result == ButtonResult.OK) { //水听器数据采集完毕,开始计算 StartCalculateData(); } }); }); //数字键盘 _eventAggregator.GetEvent<NumericKeypadEvent>().Subscribe(delegate(NumberStruct number) { if (number.TextBoxName.Equals(_mainWindow.PipeDiameterTextBox.Name)) { PipeDiameter = number.NumberValue; } else if (number.TextBoxName.Equals(_mainWindow.PipeLengthTextBox.Name)) { PipeLength = number.NumberValue; } else if (number.TextBoxName.Equals(_mainWindow.LowFrequencyTextBox.Name)) { LowFrequency = number.NumberValue; } else if (number.TextBoxName.Equals(_mainWindow.HighFrequencyTextBox.Name)) { HighFrequency = number.NumberValue; } }); } private void StartCalculateData() { DialogHub.Get.ShowLoadingDialog(_mainWindow, "数据计算中,请稍后..."); //开始计算就不收集收据了且不能点击开始按钮 StartButtonEnabled = false; using (var manager = new DataBaseManager()) { var today = DateTime.Now.ToString("yyyyMMdd"); var configModel = manager.Table<CorrelatorConfigModel>() .Where(x => x.Date == today) .OrderBy(x => x.Date) .LastOrDefault() ?? new CorrelatorConfigModel { Date = today, Pipe = 1, LocateTimes = 1, ListenTimes = 1 }; //如果配置里面的日期相同,则取配置里面的Pipe作为index,如果配置里面的日期不相同,则默认index=1 var pipeIndex = configModel.Date.Equals(today) ? configModel.Pipe : 1; _locateDataDir = DirectoryManager.GetLocateDataDir(pipeIndex); _locateTimes = configModel.LocateTimes; //插入新纪录 configModel.Pipe++; configModel.LocateTimes++; manager.Insert(configModel); } //计算 var dataModel = RuntimeCache.CorrelatorData; if (dataModel.LeftDeviceDataArray == null || dataModel.RightDeviceDataArray == null) { "MainWindowViewModel".WriteLog("数据未收集完整,请稍后..."); return; } if (_backgroundWorker.IsBusy) { "MainWindowViewModel".WriteLog("正在计算中,请稍后..."); return; } //设置噪声值 CorrelatorData = dataModel; _backgroundWorker.RunWorkerAsync(); } /// <summary> /// 各种定时器 /// </summary> private void TimerTick() { //实时刷新显示最新一条指令 _commandTimer.Tick += delegate { LastCommand = _commandService.GetLastCommand(); }; _commandTimer.Start(); _checkSerialPortTimer.Tick += delegate { var ports = SerialPort.GetPortNames(); foreach (var portName in ports) { if (portName != RuntimeCache.PortName || _serialPortService.Sp.IsOpen) continue; _serialPortService.Sp.PortName = portName; //串口名称 _serialPortService.Sp.BaudRate = 230400; //波特率57600和230400 _serialPortService.Sp.DataBits = 8; //数据位 _serialPortService.Sp.StopBits = (StopBits)1; //停止位 _serialPortService.Sp.Open(); //打开串口 "MainWindowViewModel".WriteLog("打开串口"); ConnectColorBrush = "LimeGreen"; break; } if (_serialPortService.Sp.IsOpen) { //实时显示信号电量 _serialPortService.ShowSignal(); } }; _checkSerialPortTimer.Start(); //实时显示时间 _timer.Tick += delegate { CurrentTime = $"{_today}" + $"\x20\x20\x20{_week}\x20\x20" + DateTime.Now.ToString("HH:mm:ss"); }; _timer.Start(); //获取电池电量 var sysPower = new SystemConfig.SystemPowerStatus(); GetSystemPowerStatus(ref sysPower); ComputerBattery = sysPower.BatteryPercent == 255 ? 100 : sysPower.BatteryPercent; _batteryTimer.Tick += delegate { GetSystemPowerStatus(ref sysPower); ComputerBattery = sysPower.BatteryPercent == 255 ? 100 : sysPower.BatteryPercent; }; _batteryTimer.Start(); //计算时间Timer _runningTimer.Tick += delegate { _runningSeconds++; ElapseTime = _runningSeconds.ToString(); }; //自动截屏Timer _snapShotTimer.Tick += delegate { _snapShotTimer.Stop(); if (!string.IsNullOrEmpty(_snapShotPath)) { _snapShotPath.SnapShot(); "MainWindowViewModel".WriteLog("截屏路径:" + _snapShotPath); } }; } /// <summary> /// 事件指令 /// </summary> private void InitDelegateCommand() { //界面加载完成 WindowLoadedCommand = new DelegateCommand<MainWindow>(it => { _mainWindow = it; "MainWindowViewModel".WriteLog("加载"); it.AccelerationRadioButton.Checked += delegate { RuntimeCache.IsHydrophone = false; FrequencyInterval = "100 ~ 3000Hz"; }; it.HydrophonesRadioButton.Checked += delegate { RuntimeCache.IsHydrophone = true; FrequencyInterval = "10 ~ 300Hz"; }; }); //退出应用 CloseWindowCommand = new DelegateCommand(delegate { _dialogService.ShowDialog("AlertControlDialog", new DialogParameters { { "AlertType", AlertType.Question }, { "Title", "温馨提示" }, { "Message", "是否确定退出应用?" } }, delegate(IDialogResult dialogResult) { if (dialogResult.Result == ButtonResult.Cancel) { return; } //删除小于50K的音频 foreach (var file in RuntimeCache.SmallAudioFiles) { File.Delete(file); } RuntimeCache.SmallAudioFiles.Clear(); _mainWindow.Close(); } ); }); //打开图片、音频菜单 OpenFolderCommand = new DelegateCommand<Popup>(delegate(Popup popup) { popup.IsOpen = true; }); //查看图片列表 OpenImageFileCommand = new DelegateCommand<Popup>(delegate(Popup popup) { _dialogService.Show("PictureFileView", null, delegate { }); popup.IsOpen = false; }); //查看音频列表 OpenAudioFileCommand = new DelegateCommand<Popup>(delegate(Popup popup) { _dialogService.Show("AudioFileView", null, delegate { }); popup.IsOpen = false; }); //打开听音 OpenListenAudioCommand = new DelegateCommand(delegate { if (!_serialPortService.Sp.IsOpen) { ShowAlertMessageDialog(AlertType.Error, "操作错误", "串口状态异常,无法打开听音功能"); return; } _dialogService.Show("SimplyAuditionDialog", null, delegate { }); }); //噪声探测 DetectNoiseCommand = new DelegateCommand(delegate { if (!_serialPortService.Sp.IsOpen) { ShowAlertMessageDialog(AlertType.Error, "操作错误", "串口状态异常,无法打开探测功能"); return; } _dialogService.Show("DetectNoiseDialog", null, delegate { }); }); //扩展 ExtensionsCommand = new DelegateCommand<Popup>(delegate(Popup popup) { popup.IsOpen = true; }); //采样率 SoundSampleRateCommand = new DelegateCommand<Popup>(delegate(Popup popup) { _dialogService.Show("SoundSampleRateDialog", null, delegate { }); popup.IsOpen = false; }); //声速 SoundSpeedCommand = new DelegateCommand<Popup>(delegate(Popup popup) { if (string.IsNullOrEmpty(_materialName)) { ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "请选择管道材料"); return; } _dialogService.Show("SoundSpeedDialog", new DialogParameters { { "MaterialName", _materialName } }, delegate { } ); popup.IsOpen = false; }); //导入水听器数据 ImportDataCommand = new DelegateCommand<Popup>(delegate(Popup popup) { if (RuntimeCache.IsHydrophone) { _dialogService.Show("ImportResponseDialog", null, delegate(IDialogResult result) { if (result.Result == ButtonResult.Cancel) { ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "用户取消导入数据"); return; } if (result.Result == ButtonResult.OK) { var configModel = result.Parameters.GetValue<ParamConfigModel>("ParamConfigModel"); MaterialName = configModel.PipeMaterial; PipeDiameter = configModel.PipeDiameter; PipeLength = configModel.PipeLength; LowFrequency = configModel.MinFrequency; HighFrequency = configModel.MaxFrequency; //计算声速 var soundVelocity = _dataService.GetSoundVelocity( _materialName, Convert.ToInt32(_pipeDiameter) ); SoundSpeed = soundVelocity.ToString(); } //导入数据完成,可以计算数据 StartCalculateData(); }); } else { ShowAlertMessageDialog(AlertType.Error, "操作错误", "仅支持水听器模式导入数据"); } popup.IsOpen = false; }); //设置 HelpCenterCommand = new DelegateCommand<Popup>(delegate(Popup popup) { popup.IsOpen = true; }); //查看日志 ShowLogCommand = new DelegateCommand<Popup>(delegate(Popup popup) { try { var file = new DirectoryInfo(DirectoryManager.LogDirPath) .GetFiles("*.log", SearchOption.AllDirectories) .OrderBy(f => f.LastWriteTime) .Reverse() .First(); if (file == null) { ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "暂时没有日志生成,请稍后再试"); return; } _dialogService.Show("ApplicationLogView", new DialogParameters { { "LogFullName", file.FullName } }, delegate { } ); popup.IsOpen = false; } catch (DirectoryNotFoundException e) { ShowAlertMessageDialog(AlertType.Error, "温馨提示", e.Message); } }); //查看软件、协议版本 ShowApplicationInfoCommand = new DelegateCommand<Popup>(delegate(Popup popup) { _dialogService.Show("ApplicationInfoDialog", null, delegate { }); popup.IsOpen = false; }); //打开Matlab波形 ShowWaveCommand = new DelegateCommand(delegate { if (RuntimeCache.CorrelatorData == null) { ShowAlertMessageDialog(AlertType.Error, "温馨提示", "请先采集数据"); return; } _dialogService.Show("NoiseWaveView", null, delegate { }); }); //打开数字键盘 OpenNumericKeypadCommand = new DelegateCommand(delegate { _dialogService.ShowDialog("NumericKeypadDialog", null, delegate { }); }); //管道材料选择 PipeItemSelectedCommand = new DelegateCommand<ComboBox>(delegate(ComboBox box) { MaterialName = box.SelectedItem.ToString(); }); //将采集的数据转为音频并保存 SaveAudioCommand = new DelegateCommand(delegate { if (_locateDataDir != null) { var redValueSortResult = from pair in RuntimeCache.RedSensorOriginalResp orderby pair.Key select pair; var redValueCollection = redValueSortResult.Select(valuePair => valuePair.Value).ToList(); var redTags = redValueCollection.Select(data => data.HandleLocalData()).ToList(); var redPcmArray = new List<byte[]>(); foreach (var tag in redTags) { var dataValue = tag.DataValue; //PCM数据 var pcm = new byte[_soundSampleRate * 3]; //每个采样点2字节 for (var i = 0; i < _soundSampleRate; i++) { pcm[i * 3 + 2] = dataValue[i * 2 + 0]; pcm[i * 3 + 1] = dataValue[i * 2 + 1]; pcm[i * 3 + 0] = 0x00; } redPcmArray.Add(pcm); } _audioService.Write(_locateDataDir, "音频_红", redPcmArray); var blueValueSortResult = from pair in RuntimeCache.BlueSensorOriginalResp orderby pair.Key select pair; var blueValueCollection = blueValueSortResult.Select(valuePair => valuePair.Value).ToList(); var blueTags = blueValueCollection.Select(data => data.HandleLocalData()).ToList(); var bluePcmArray = new List<byte[]>(); foreach (var tag in blueTags) { var dataValue = tag.DataValue; //PCM数据 var pcm = new byte[_soundSampleRate * 3]; //每个采样点2字节 for (var i = 0; i < _soundSampleRate; i++) { pcm[i * 3 + 2] = dataValue[i * 2 + 0]; pcm[i * 3 + 1] = dataValue[i * 2 + 1]; pcm[i * 3 + 0] = 0x00; } bluePcmArray.Add(pcm); } _audioService.Write(_locateDataDir, "音频_蓝", bluePcmArray); Growl.Success("音频已保存"); } else { ShowAlertMessageDialog(AlertType.Error, "温馨提示", "请先采集数据"); } }); //复位 ResetParamCommand = new DelegateCommand(delegate { ResetParam(true); }); //截屏 SnapShotCommand = new DelegateCommand(delegate { var filePath = $"{DirectoryManager.GetPictureDir()}\\快照_{DateTime.Now:yyyyMMddHHmmss}.png"; filePath.SnapShot(); }); //开始采集数据 StartCollectDataCommand = new DelegateCommand(delegate { if (!_serialPortService.Sp.IsOpen) { ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "串口状态异常,无法操作"); return; } if (CheckParamLegitimacy()) { //每次计算之前都需要判断是否已经完成之前的计算,然后清空上一次的计算数据 ResetParam(false); //开始数据采集 if (RuntimeCache.IsHydrophone) { RuntimeCache.WorkMode = 2; _commandService.SendHydrophoneWakeUpCmd(_serialPortService.Sp); } else { RuntimeCache.WorkMode = 1; _commandService.SendCorrelatorWakeUpCmd(_serialPortService.Sp); } SoundSampleRate = _dataService.GetSampleRateByWorkMode(RuntimeCache.WorkMode); RuntimeCache.IsDetectNoise = false; //记录计算时间 _runningTimer.Start(); } }); } /// <summary> /// 重置参数 /// </summary> /// <param name="isResetParam"></param> private void ResetParam(bool isResetParam) { if (isResetParam) { PipeDiameter = string.Empty; PipeLength = string.Empty; LowFrequency = string.Empty; HighFrequency = string.Empty; SoundSpeed = "0"; //复位之后可以再次开始 StartButtonEnabled = true; //清空上次的缓存 RuntimeCache.CorrelatorData = null; } InterferenceFrequency = "无"; Snr = "无"; FilterValue = " ~ Hz"; RedTransmitterDistance = 0; ElapseTime = "0"; BlueTransmitterDistance = 0; CorrelatorData = new CorrelatorDataModel(); ClearCache(); _runningSeconds = 0; _runningTimer.Stop(); _eventAggregator.GetEvent<ClearOscillogramEvent>().Publish(); } /// <summary> /// 清空上次计算的缓存 /// </summary> private void ClearCache() { RuntimeCache.RedSensorOriginalResp.Clear(); RuntimeCache.BlueSensorOriginalResp.Clear(); RuntimeCache.RedSensorResponseTags.Clear(); RuntimeCache.BlueSensorResponseTags.Clear(); } /// <summary> /// 参数检查 /// </summary> /// <returns></returns> private bool CheckParamLegitimacy() { if (string.IsNullOrEmpty(_materialName)) { ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "请选择管道材料"); return false; } if (string.IsNullOrEmpty(_pipeDiameter)) { ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "请输入管道直径"); return false; } if (string.IsNullOrEmpty(_pipeLength)) { ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "请输入管道长度"); return false; } if (string.IsNullOrEmpty(_lowFrequency) || string.IsNullOrEmpty(_highFrequency)) { ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "请输入完整的计算频段"); return false; } var low = Convert.ToInt32(_lowFrequency); var high = Convert.ToInt32(_highFrequency); if (RuntimeCache.IsHydrophone) { if (low < 10 || low > 300 || high < 10 || high > 300 || low >= high) { ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "频段范围10 ~ 300Hz,请重新输入"); return false; } //缓存计算参数 _paramConfig = new ParamConfigModel { PipeMaterial = _materialName, PipeDiameter = _pipeDiameter, PipeLength = _pipeLength, MinFrequency = _lowFrequency, MaxFrequency = _highFrequency }; } else { if (low < 100 || low > 3000 || high < 100 || high > 3000 || low >= high) { ShowAlertMessageDialog(AlertType.Warning, "温馨提示", "频段范围100 ~ 3000Hz,请重新输入"); return false; } } //声速 var soundVelocity = _dataService.GetSoundVelocity(_materialName, Convert.ToInt32(_pipeDiameter)); SoundSpeed = soundVelocity.ToString(); return true; } /// <summary> /// 后台计算 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Worker_OnDoWork(object sender, DoWorkEventArgs e) { try { "MainWindowViewModel".WriteLog("开始计算"); var array = LazyCorrelator.Value.locating( 11, (MWNumericArray)_correlatorData.LeftDeviceDataArray, (MWNumericArray)_correlatorData.RightDeviceDataArray, _soundSampleRate, int.Parse(_pipeLength), int.Parse(_soundSpeed), 0, 0, 0, 0, _materialName, int.Parse(_pipeDiameter), int.Parse(_pipeDiameter), 1, -1, -1, -1, int.Parse(_lowFrequency), int.Parse(_highFrequency) ); e.Result = array; } catch (Exception) { _runningTimer.Stop(); DialogHub.Get.DismissLoadingDialog(); Application.Current.Dispatcher.Invoke(delegate { _dialogService.ShowDialog("AlertControlDialog", new DialogParameters { { "AlertType", AlertType.Question }, { "Title", "温馨提示" }, { "Message", "计算出现错误,请重新计算" } }, delegate(IDialogResult dialogResult) { if (dialogResult.Result == ButtonResult.Cancel) { return; } StartButtonEnabled = true; ClearCache(); } ); }); } } private void Worker_OnProgressChanged(object sender, ProgressChangedEventArgs e) { } private void Worker_OnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { "MainWindowViewModel".WriteLog("计算结束"); DialogHub.Get.DismissLoadingDialog(); var array = (MWArray[])e.Result; //数据绑定 var snr = Convert.ToDouble(array[0].ToString()); //信噪比 Snr = snr.ToString("0.0") + ":1"; RedTransmitterDistance = Convert.ToDouble(array[1].ToString()); //距离A BlueTransmitterDistance = Convert.ToDouble(array[2].ToString()); //距离B var maxFreLowOut = Convert.ToInt32(array[6].ToString()); //低频 var maxFreHighOut = Convert.ToInt32(array[7].ToString()); //高频 FilterValue = maxFreLowOut + " ~ " + maxFreHighOut + "Hz"; _eventAggregator.GetEvent<RenderOscillogramEvent>().Publish(array); var time = DateTime.Now.ToString("HHmmss"); if (RuntimeCache.IsHydrophone) { //保存参数 var paramConfigFile = $"{_locateDataDir}\\参数配置.{_locateTimes}.{time}.json"; File.AppendAllText(paramConfigFile, JsonConvert.SerializeObject(_paramConfig)); } //保存数据 var fileName = $"{_locateDataDir}\\测试数据.{_locateTimes}.{time}.txt"; fileName.SaveLocateData(_correlatorData); "MainWindowViewModel".WriteLog("定位数据路径:" + fileName); //保存了数据之后3s再截图 _snapShotPath = $"{_locateDataDir}\\快照.{_locateTimes}.{time}.png"; _snapShotTimer.Start(); _runningTimer.Stop(); StartButtonEnabled = true; } /// <summary> /// 显示普通提示对话框 /// </summary> private void ShowAlertMessageDialog(AlertType type, string title, string message) { _dialogService.ShowDialog("AlertMessageDialog", new DialogParameters { { "AlertType", type }, { "Title", title }, { "Message", message } }, delegate { } ); } } }