diff --git a/Correlator/DataService/SerialPortServiceImpl.cs b/Correlator/DataService/SerialPortServiceImpl.cs index aa0b98f..a0a4b15 100644 --- a/Correlator/DataService/SerialPortServiceImpl.cs +++ b/Correlator/DataService/SerialPortServiceImpl.cs @@ -27,34 +27,31 @@ { _eventAggregator = eventAggregator; _audioService = audioService; - Sp.DataReceived += DataReceivedFromSerialPort; + Sp.DataReceived += delegate + { + while (Sp.BytesToRead < 4) + { + return; + } + + var headerBuff = new byte[2]; + Sp.Read(headerBuff, 0, 2); //读取数据 + if (headerBuff[0] != 0xA3 || headerBuff[1] != 0x20) //符合规范 + { + "SerialPortServiceImpl".WriteLog("串口数据头部校验失败"); + Sp.DiscardInBuffer(); + } + else + { + ReadFromSerialPort(headerBuff); + } + }; } /// - /// 串口数据 + /// 预处理并组装每条数据 /// - /// - /// - private void DataReceivedFromSerialPort(object sender, SerialDataReceivedEventArgs args) - { - while (Sp.BytesToRead < 4) - { - return; - } - - var headerBuff = new byte[2]; - Sp.Read(headerBuff, 0, 2); //读取数据 - if (headerBuff[0] != 0xA3 || headerBuff[1] != 0x20) //符合规范 - { - "SerialPortServiceImpl".WriteLog("串口数据头部校验失败"); - Sp.DiscardInBuffer(); - } - else - { - ReadFromSerialPort(headerBuff); - } - } - + /// private void ReadFromSerialPort(byte[] header) { var lengthBuffer = new byte[2]; @@ -145,7 +142,7 @@ break; case 30: - if (RuntimeCache.IsHydrophone && RuntimeCache.CanCollectData) + if (RuntimeCache.IsHydrophone) { Application.Current.Dispatcher.Invoke(delegate { @@ -161,30 +158,32 @@ break; case 22543: - if (receivedData[0] == 0xA3 && receivedData[1] == 0x20) - { - int index = receivedData[15]; - //取出seq,确定收到的是第几包数据 - RuntimeCache.SeqCaches.Add(index); + // if (receivedData[0] == 0xA3 && receivedData[1] == 0x20) + // { + // int index = receivedData[15]; + // //取出seq,确定收到的是第几包数据 + // RuntimeCache.SeqCaches.Add(index); + // + // var response = BitConverter.ToString(receivedData).Replace("-", ""); + // //收集数据 + // if (deviceId.Equals(RuntimeCache.Dev1)) + // { + // //原始数据 + // RuntimeCache.RedSensorOriginalResp.Add(index, response); + // //解析之后的数据 + // RuntimeCache.RedSensorResponseTags.Add(index, tags); + // } + // else + // { + // //原始数据 + // RuntimeCache.BlueSensorOriginalResp.Add(index, response); + // //解析之后的数据 + // RuntimeCache.BlueSensorResponseTags.Add(index, tags); + // } + // } - var response = BitConverter.ToString(receivedData).Replace("-", ""); - //收集数据 - if (deviceId.Equals(RuntimeCache.Dev1)) - { - //原始数据 - RuntimeCache.RedSensorOriginalResp.Add(index, response); - //解析之后的数据 - RuntimeCache.RedSensorResponseTags.Add(index, tags); - } - else - { - //原始数据 - RuntimeCache.BlueSensorOriginalResp.Add(index, response); - //解析之后的数据 - RuntimeCache.BlueSensorResponseTags.Add(index, tags); - } - } - + //TODO 采用水听器数据,但是模式是加速度计模式 + HandleCorrelatorData(deviceId, tags); break; case 15024: //听音 HandleListenData(tags); diff --git a/Correlator/DataService/SerialPortServiceImpl.cs b/Correlator/DataService/SerialPortServiceImpl.cs index aa0b98f..a0a4b15 100644 --- a/Correlator/DataService/SerialPortServiceImpl.cs +++ b/Correlator/DataService/SerialPortServiceImpl.cs @@ -27,34 +27,31 @@ { _eventAggregator = eventAggregator; _audioService = audioService; - Sp.DataReceived += DataReceivedFromSerialPort; + Sp.DataReceived += delegate + { + while (Sp.BytesToRead < 4) + { + return; + } + + var headerBuff = new byte[2]; + Sp.Read(headerBuff, 0, 2); //读取数据 + if (headerBuff[0] != 0xA3 || headerBuff[1] != 0x20) //符合规范 + { + "SerialPortServiceImpl".WriteLog("串口数据头部校验失败"); + Sp.DiscardInBuffer(); + } + else + { + ReadFromSerialPort(headerBuff); + } + }; } /// - /// 串口数据 + /// 预处理并组装每条数据 /// - /// - /// - private void DataReceivedFromSerialPort(object sender, SerialDataReceivedEventArgs args) - { - while (Sp.BytesToRead < 4) - { - return; - } - - var headerBuff = new byte[2]; - Sp.Read(headerBuff, 0, 2); //读取数据 - if (headerBuff[0] != 0xA3 || headerBuff[1] != 0x20) //符合规范 - { - "SerialPortServiceImpl".WriteLog("串口数据头部校验失败"); - Sp.DiscardInBuffer(); - } - else - { - ReadFromSerialPort(headerBuff); - } - } - + /// private void ReadFromSerialPort(byte[] header) { var lengthBuffer = new byte[2]; @@ -145,7 +142,7 @@ break; case 30: - if (RuntimeCache.IsHydrophone && RuntimeCache.CanCollectData) + if (RuntimeCache.IsHydrophone) { Application.Current.Dispatcher.Invoke(delegate { @@ -161,30 +158,32 @@ break; case 22543: - if (receivedData[0] == 0xA3 && receivedData[1] == 0x20) - { - int index = receivedData[15]; - //取出seq,确定收到的是第几包数据 - RuntimeCache.SeqCaches.Add(index); + // if (receivedData[0] == 0xA3 && receivedData[1] == 0x20) + // { + // int index = receivedData[15]; + // //取出seq,确定收到的是第几包数据 + // RuntimeCache.SeqCaches.Add(index); + // + // var response = BitConverter.ToString(receivedData).Replace("-", ""); + // //收集数据 + // if (deviceId.Equals(RuntimeCache.Dev1)) + // { + // //原始数据 + // RuntimeCache.RedSensorOriginalResp.Add(index, response); + // //解析之后的数据 + // RuntimeCache.RedSensorResponseTags.Add(index, tags); + // } + // else + // { + // //原始数据 + // RuntimeCache.BlueSensorOriginalResp.Add(index, response); + // //解析之后的数据 + // RuntimeCache.BlueSensorResponseTags.Add(index, tags); + // } + // } - var response = BitConverter.ToString(receivedData).Replace("-", ""); - //收集数据 - if (deviceId.Equals(RuntimeCache.Dev1)) - { - //原始数据 - RuntimeCache.RedSensorOriginalResp.Add(index, response); - //解析之后的数据 - RuntimeCache.RedSensorResponseTags.Add(index, tags); - } - else - { - //原始数据 - RuntimeCache.BlueSensorOriginalResp.Add(index, response); - //解析之后的数据 - RuntimeCache.BlueSensorResponseTags.Add(index, tags); - } - } - + //TODO 采用水听器数据,但是模式是加速度计模式 + HandleCorrelatorData(deviceId, tags); break; case 15024: //听音 HandleListenData(tags); diff --git a/Correlator/Util/RuntimeCache.cs b/Correlator/Util/RuntimeCache.cs index e2e9b75..9b3ed80 100644 --- a/Correlator/Util/RuntimeCache.cs +++ b/Correlator/Util/RuntimeCache.cs @@ -10,11 +10,6 @@ public class RuntimeCache { /// - /// 是否可以收集数据 - /// - public static bool CanCollectData = false; - - /// /// 红色传感器是否正常 /// public static bool RedSensorIsEnable = false; diff --git a/Correlator/DataService/SerialPortServiceImpl.cs b/Correlator/DataService/SerialPortServiceImpl.cs index aa0b98f..a0a4b15 100644 --- a/Correlator/DataService/SerialPortServiceImpl.cs +++ b/Correlator/DataService/SerialPortServiceImpl.cs @@ -27,34 +27,31 @@ { _eventAggregator = eventAggregator; _audioService = audioService; - Sp.DataReceived += DataReceivedFromSerialPort; + Sp.DataReceived += delegate + { + while (Sp.BytesToRead < 4) + { + return; + } + + var headerBuff = new byte[2]; + Sp.Read(headerBuff, 0, 2); //读取数据 + if (headerBuff[0] != 0xA3 || headerBuff[1] != 0x20) //符合规范 + { + "SerialPortServiceImpl".WriteLog("串口数据头部校验失败"); + Sp.DiscardInBuffer(); + } + else + { + ReadFromSerialPort(headerBuff); + } + }; } /// - /// 串口数据 + /// 预处理并组装每条数据 /// - /// - /// - private void DataReceivedFromSerialPort(object sender, SerialDataReceivedEventArgs args) - { - while (Sp.BytesToRead < 4) - { - return; - } - - var headerBuff = new byte[2]; - Sp.Read(headerBuff, 0, 2); //读取数据 - if (headerBuff[0] != 0xA3 || headerBuff[1] != 0x20) //符合规范 - { - "SerialPortServiceImpl".WriteLog("串口数据头部校验失败"); - Sp.DiscardInBuffer(); - } - else - { - ReadFromSerialPort(headerBuff); - } - } - + /// private void ReadFromSerialPort(byte[] header) { var lengthBuffer = new byte[2]; @@ -145,7 +142,7 @@ break; case 30: - if (RuntimeCache.IsHydrophone && RuntimeCache.CanCollectData) + if (RuntimeCache.IsHydrophone) { Application.Current.Dispatcher.Invoke(delegate { @@ -161,30 +158,32 @@ break; case 22543: - if (receivedData[0] == 0xA3 && receivedData[1] == 0x20) - { - int index = receivedData[15]; - //取出seq,确定收到的是第几包数据 - RuntimeCache.SeqCaches.Add(index); + // if (receivedData[0] == 0xA3 && receivedData[1] == 0x20) + // { + // int index = receivedData[15]; + // //取出seq,确定收到的是第几包数据 + // RuntimeCache.SeqCaches.Add(index); + // + // var response = BitConverter.ToString(receivedData).Replace("-", ""); + // //收集数据 + // if (deviceId.Equals(RuntimeCache.Dev1)) + // { + // //原始数据 + // RuntimeCache.RedSensorOriginalResp.Add(index, response); + // //解析之后的数据 + // RuntimeCache.RedSensorResponseTags.Add(index, tags); + // } + // else + // { + // //原始数据 + // RuntimeCache.BlueSensorOriginalResp.Add(index, response); + // //解析之后的数据 + // RuntimeCache.BlueSensorResponseTags.Add(index, tags); + // } + // } - var response = BitConverter.ToString(receivedData).Replace("-", ""); - //收集数据 - if (deviceId.Equals(RuntimeCache.Dev1)) - { - //原始数据 - RuntimeCache.RedSensorOriginalResp.Add(index, response); - //解析之后的数据 - RuntimeCache.RedSensorResponseTags.Add(index, tags); - } - else - { - //原始数据 - RuntimeCache.BlueSensorOriginalResp.Add(index, response); - //解析之后的数据 - RuntimeCache.BlueSensorResponseTags.Add(index, tags); - } - } - + //TODO 采用水听器数据,但是模式是加速度计模式 + HandleCorrelatorData(deviceId, tags); break; case 15024: //听音 HandleListenData(tags); diff --git a/Correlator/Util/RuntimeCache.cs b/Correlator/Util/RuntimeCache.cs index e2e9b75..9b3ed80 100644 --- a/Correlator/Util/RuntimeCache.cs +++ b/Correlator/Util/RuntimeCache.cs @@ -10,11 +10,6 @@ public class RuntimeCache { /// - /// 是否可以收集数据 - /// - public static bool CanCollectData = false; - - /// /// 红色传感器是否正常 /// public static bool RedSensorIsEnable = false; diff --git a/Correlator/ViewModels/MainWindowViewModel.cs b/Correlator/ViewModels/MainWindowViewModel.cs index 87a509b..1a2614e 100644 --- a/Correlator/ViewModels/MainWindowViewModel.cs +++ b/Correlator/ViewModels/MainWindowViewModel.cs @@ -1,11 +1,11 @@ using System; 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.Threading; using System.Windows; using System.Windows.Controls.Primitives; using System.Windows.Threading; @@ -28,7 +28,7 @@ { public class MainWindowViewModel : BindableBase { - #region 变量 + #region DispatcherTimer private readonly DispatcherTimer _checkSerialPortTimer = new DispatcherTimer { @@ -45,8 +45,6 @@ Interval = TimeSpan.FromMinutes(5) }; - //计算时间 - private int _runningSeconds; //运行时间Timer private readonly DispatcherTimer _runningTimer = new DispatcherTimer @@ -54,36 +52,44 @@ Interval = TimeSpan.FromSeconds(1) }; - private bool _isResetParam; - - private readonly IEventAggregator _eventAggregator; - private readonly IApplicationDataService _soundSpeedDataService; - private readonly IDialogService _dialogService; - private readonly ISerialPortService _serialPortService; - - //加速度计下发指令Timer - private readonly DispatcherTimer _accelerometerCommandTimer = new DispatcherTimer - { - Interval = TimeSpan.FromSeconds(10) - }; - - private MainWindow _mainWindow; - private byte _devId = 0x02; - private string _locateDataDir; - private int _locateTimes; - private string _snapShotPath = string.Empty; - private ParamConfigModel _paramConfig; - //自动截屏倒计时 private readonly DispatcherTimer _snapShotTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(3) }; + #endregion + + #region 变量 + + private readonly IEventAggregator _eventAggregator; + private readonly IApplicationDataService _soundSpeedDataService; + private readonly IDialogService _dialogService; + private readonly ISerialPortService _serialPortService; + private readonly BackgroundWorker _backgroundWorker; + private readonly string _today; + private readonly string _week; + private MainWindow _mainWindow; + private bool _isResetParam; + private byte _devId = 0x02; + private string _locateDataDir; + private int _locateTimes; + private string _snapShotPath = string.Empty; + private ParamConfigModel _paramConfig; + + //计算时间 + private int _runningSeconds; + //Matlab算法 private static readonly Lazy LazyCorrelator = new Lazy(() => new CorrelatorSingle.Correlator()); + /// + /// 加速度:1 + /// 水听器:2 + /// + private int _workModel = 1; + #endregion #region VM属性 @@ -471,9 +477,13 @@ _dialogService = dialogService; _serialPortService = serialPortService; - RegisterMessage(); - - TimerTick(); + // 算法计算后台任务 + _backgroundWorker = new BackgroundWorker(); + _backgroundWorker.WorkerReportsProgress = true; + _backgroundWorker.WorkerSupportsCancellation = true; + _backgroundWorker.DoWork += Worker_OnDoWork; + _backgroundWorker.ProgressChanged += Worker_OnProgressChanged; + _backgroundWorker.RunWorkerCompleted += Worker_OnRunWorkerCompleted; _pipeMaterialsArray = new ObservableCollection(); var pipeMaterials = dataService.GetPipeMaterial(); @@ -482,6 +492,14 @@ PipeMaterialsArray.Add(material.ChineseMaterial); } + //获取当前日期,星期 + _today = DateTime.Now.ToString("yyyy年MM月dd日"); + _week = DateTime.Now.ToString("dddd", new CultureInfo("zh-cn")); + + RegisterMessage(); + + TimerTick(); + InitDelegateCommand(); } @@ -567,13 +585,6 @@ DialogHub.Get.ShowLoadingDialog(_mainWindow, "数据计算中,请稍后..."); //开始计算就不收集收据了且不能点击开始按钮 StartButtonEnabled = false; - RuntimeCache.CanCollectData = false; - if (!RuntimeCache.IsHydrophone) - { - //开始计算停止收集指令 - _accelerometerCommandTimer.Stop(); - } - using (var manager = new DataBaseManager()) { var today = DateTime.Now.ToString("yyyyMMdd"); @@ -594,100 +605,22 @@ } //计算 - new Thread(CalculateData).Start(); - } - - /// - /// 算法计算 - /// - private void CalculateData() - { var dataModel = RuntimeCache.CorrelatorData; - if (dataModel.LeftDeviceDataArray != null && dataModel.RightDeviceDataArray != null) + if (dataModel.LeftDeviceDataArray == null || dataModel.RightDeviceDataArray == null) { - try - { - "MainWindowViewModel".WriteLog("开始计算"); - var array = LazyCorrelator.Value.locating( - 11, - (MWNumericArray)dataModel.LeftDeviceDataArray, (MWNumericArray)dataModel.RightDeviceDataArray, - RuntimeCache.AudioSampleRate, - 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) - ); - "MainWindowViewModel".WriteLog("计算结束"); - DialogHub.Get.DismissLoadingDialog(); - - //数据绑定 - 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"; - - //设置噪声值 - CorrelatorData = dataModel; - - _eventAggregator.GetEvent().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(dataModel); - "MainWindowViewModel".WriteLog("定位数据路径:" + fileName); - - //保存了数据之后3s再截图 - _snapShotPath = $"{_locateDataDir}\\快照.{_locateTimes}.{time}.png"; - _snapShotTimer.Start(); - - _runningTimer.Stop(); - StartButtonEnabled = true; - ResetCache(); - } - 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; - ResetCache(); - } - ); - }); - } + "MainWindowViewModel".WriteLog("数据未收集完整,请稍后..."); + return; } + + if (_backgroundWorker.IsBusy) + { + "MainWindowViewModel".WriteLog("正在计算中,请稍后..."); + return; + } + + //设置噪声值 + CorrelatorData = dataModel; + _backgroundWorker.RunWorkerAsync(); } /// @@ -706,8 +639,9 @@ _serialPortService.Sp.DataBits = 8; //数据位 _serialPortService.Sp.StopBits = (StopBits)1; //停止位 _serialPortService.Sp.Open(); //打开串口 - Console.WriteLine(@"MainWindowViewModel => 打开串口"); + "MainWindowViewModel".WriteLog("打开串口"); + ConnectColorBrush = "LimeGreen"; break; } @@ -736,7 +670,10 @@ _checkSerialPortTimer.Start(); //实时显示时间 - _timer.Tick += RealTime; + _timer.Tick += delegate + { + CurrentTime = $"{_today}" + $"\x20\x20\x20{_week}\x20\x20" + DateTime.Now.ToString("HH:mm:ss"); + }; _timer.Start(); //获取电池电量 @@ -758,16 +695,6 @@ ElapseTime = _runningSeconds.ToString(); }; - //加速度计下发指令Timer - _accelerometerCommandTimer.Tick += delegate - { - if (RuntimeCache.CanCollectData) - { - RuntimeCache.IsDetectNoise = false; - CommandSender.SendCorrelatorWakeUpCmd(_serialPortService.Sp); - } - }; - //自动截屏Timer _snapShotTimer.Tick += delegate { @@ -789,7 +716,7 @@ WindowLoadedCommand = new DelegateCommand(it => { _mainWindow = it; - Console.WriteLine(@"MainWindowViewModel => 加载"); + "MainWindowViewModel".WriteLog("加载"); it.AccelerationRadioButton.Checked += delegate { RuntimeCache.IsHydrophone = false; @@ -806,9 +733,7 @@ //退出应用 CloseWindowCommand = new DelegateCommand(delegate { - _dialogService.ShowDialog( - "AlertControlDialog", - new DialogParameters + _dialogService.ShowDialog("AlertControlDialog", new DialogParameters { { "AlertType", AlertType.Question }, { "Title", "温馨提示" }, { "Message", "是否确定退出应用?" } }, @@ -1013,16 +938,11 @@ //每次计算之前都需要判断是否已经完成之前的计算,然后清空上一次的计算数据 ResetParam(); - RuntimeCache.CanCollectData = true; //开始数据采集 - if (RuntimeCache.IsHydrophone) - { - CommandSender.SendHydrophoneWakeUpCmd(_serialPortService.Sp); - } - else - { - _accelerometerCommandTimer.Start(); - } + _workModel = RuntimeCache.IsHydrophone ? 2 : 1; + "MainWindowViewModel".WriteLog("工作模式:" + _workModel); + RuntimeCache.IsDetectNoise = false; + CommandSender.SendCorrelatorWakeUpCmd(_serialPortService.Sp); //记录计算时间 _runningTimer.Start(); @@ -1062,28 +982,19 @@ _runningTimer.Stop(); _eventAggregator.GetEvent().Publish(); - - if (!RuntimeCache.IsHydrophone) - { - _accelerometerCommandTimer.Stop(); - } - - RuntimeCache.CanCollectData = false; } /// - /// 重置上次计算的缓存 + /// 清空上次计算的缓存 /// - private void ResetCache() + private void ClearCache() { RuntimeCache.RedSensorOriginalResp.Clear(); RuntimeCache.BlueSensorOriginalResp.Clear(); RuntimeCache.RedSensorResponseTags.Clear(); RuntimeCache.BlueSensorResponseTags.Clear(); - RuntimeCache.RedSensorIsEnable = false; - RuntimeCache.BlueSensorIsEnable = false; } - + /// /// 参数检查 /// @@ -1144,7 +1055,6 @@ } } - //声速 var soundVelocity = _soundSpeedDataService.GetSoundVelocity(_materialName, Convert.ToInt32(_pipeDiameter)); SoundSpeed = soundVelocity.ToString(); @@ -1152,41 +1062,101 @@ } /// - /// 实时显示时间,并监听串口状态 + /// 后台计算 /// /// - /// - private void RealTime(object sender, EventArgs args) + /// + private void Worker_OnDoWork(object sender, DoWorkEventArgs e) { - var dateTime = DateTime.Now; - var strDateTime = dateTime.ToString("yyyy年MM月dd日") + - dateTime.ToString("\0 \0 \0 dddd \0 \0 \0", new CultureInfo("zh-cn")) + - dateTime.ToString("HH:mm:ss"); - Application.Current.Dispatcher.Invoke(delegate + try { - CurrentTime = strDateTime; + "MainWindowViewModel".WriteLog("开始计算"); + var array = LazyCorrelator.Value.locating( + 11, + (MWNumericArray)_correlatorData.LeftDeviceDataArray, + (MWNumericArray)_correlatorData.RightDeviceDataArray, + RuntimeCache.AudioSampleRate, + 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), + _workModel + ); + e.Result = array; + } + catch (Exception) + { + _runningTimer.Stop(); + DialogHub.Get.DismissLoadingDialog(); - //同时监听串口状态 - if (_serialPortService.Sp.IsOpen) + Application.Current.Dispatcher.Invoke(delegate { - ConnectColorBrush = "LimeGreen"; - } - else - { - ConnectColorBrush = "LightGray"; + _dialogService.ShowDialog("AlertControlDialog", new DialogParameters + { + { "AlertType", AlertType.Question }, { "Title", "温馨提示" }, { "Message", "计算出现错误,请重新计算" } + }, + delegate(IDialogResult dialogResult) + { + if (dialogResult.Result == ButtonResult.Cancel) + { + return; + } - RedTransmitterBattery = 0; - RedTransmitterSignal = 0; - RedTransmitterState = false; + StartButtonEnabled = true; + ClearCache(); + } + ); + }); + } + } - BlueTransmitterBattery = 0; - BlueTransmitterSignal = 0; - BlueTransmitterState = false; + private void Worker_OnProgressChanged(object sender, ProgressChangedEventArgs e) + { + } - RuntimeCache.RedSensorIsEnable = false; - RuntimeCache.BlueSensorIsEnable = false; - } - }); + 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().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; + ClearCache(); } /// diff --git a/Correlator/DataService/SerialPortServiceImpl.cs b/Correlator/DataService/SerialPortServiceImpl.cs index aa0b98f..a0a4b15 100644 --- a/Correlator/DataService/SerialPortServiceImpl.cs +++ b/Correlator/DataService/SerialPortServiceImpl.cs @@ -27,34 +27,31 @@ { _eventAggregator = eventAggregator; _audioService = audioService; - Sp.DataReceived += DataReceivedFromSerialPort; + Sp.DataReceived += delegate + { + while (Sp.BytesToRead < 4) + { + return; + } + + var headerBuff = new byte[2]; + Sp.Read(headerBuff, 0, 2); //读取数据 + if (headerBuff[0] != 0xA3 || headerBuff[1] != 0x20) //符合规范 + { + "SerialPortServiceImpl".WriteLog("串口数据头部校验失败"); + Sp.DiscardInBuffer(); + } + else + { + ReadFromSerialPort(headerBuff); + } + }; } /// - /// 串口数据 + /// 预处理并组装每条数据 /// - /// - /// - private void DataReceivedFromSerialPort(object sender, SerialDataReceivedEventArgs args) - { - while (Sp.BytesToRead < 4) - { - return; - } - - var headerBuff = new byte[2]; - Sp.Read(headerBuff, 0, 2); //读取数据 - if (headerBuff[0] != 0xA3 || headerBuff[1] != 0x20) //符合规范 - { - "SerialPortServiceImpl".WriteLog("串口数据头部校验失败"); - Sp.DiscardInBuffer(); - } - else - { - ReadFromSerialPort(headerBuff); - } - } - + /// private void ReadFromSerialPort(byte[] header) { var lengthBuffer = new byte[2]; @@ -145,7 +142,7 @@ break; case 30: - if (RuntimeCache.IsHydrophone && RuntimeCache.CanCollectData) + if (RuntimeCache.IsHydrophone) { Application.Current.Dispatcher.Invoke(delegate { @@ -161,30 +158,32 @@ break; case 22543: - if (receivedData[0] == 0xA3 && receivedData[1] == 0x20) - { - int index = receivedData[15]; - //取出seq,确定收到的是第几包数据 - RuntimeCache.SeqCaches.Add(index); + // if (receivedData[0] == 0xA3 && receivedData[1] == 0x20) + // { + // int index = receivedData[15]; + // //取出seq,确定收到的是第几包数据 + // RuntimeCache.SeqCaches.Add(index); + // + // var response = BitConverter.ToString(receivedData).Replace("-", ""); + // //收集数据 + // if (deviceId.Equals(RuntimeCache.Dev1)) + // { + // //原始数据 + // RuntimeCache.RedSensorOriginalResp.Add(index, response); + // //解析之后的数据 + // RuntimeCache.RedSensorResponseTags.Add(index, tags); + // } + // else + // { + // //原始数据 + // RuntimeCache.BlueSensorOriginalResp.Add(index, response); + // //解析之后的数据 + // RuntimeCache.BlueSensorResponseTags.Add(index, tags); + // } + // } - var response = BitConverter.ToString(receivedData).Replace("-", ""); - //收集数据 - if (deviceId.Equals(RuntimeCache.Dev1)) - { - //原始数据 - RuntimeCache.RedSensorOriginalResp.Add(index, response); - //解析之后的数据 - RuntimeCache.RedSensorResponseTags.Add(index, tags); - } - else - { - //原始数据 - RuntimeCache.BlueSensorOriginalResp.Add(index, response); - //解析之后的数据 - RuntimeCache.BlueSensorResponseTags.Add(index, tags); - } - } - + //TODO 采用水听器数据,但是模式是加速度计模式 + HandleCorrelatorData(deviceId, tags); break; case 15024: //听音 HandleListenData(tags); diff --git a/Correlator/Util/RuntimeCache.cs b/Correlator/Util/RuntimeCache.cs index e2e9b75..9b3ed80 100644 --- a/Correlator/Util/RuntimeCache.cs +++ b/Correlator/Util/RuntimeCache.cs @@ -10,11 +10,6 @@ public class RuntimeCache { /// - /// 是否可以收集数据 - /// - public static bool CanCollectData = false; - - /// /// 红色传感器是否正常 /// public static bool RedSensorIsEnable = false; diff --git a/Correlator/ViewModels/MainWindowViewModel.cs b/Correlator/ViewModels/MainWindowViewModel.cs index 87a509b..1a2614e 100644 --- a/Correlator/ViewModels/MainWindowViewModel.cs +++ b/Correlator/ViewModels/MainWindowViewModel.cs @@ -1,11 +1,11 @@ using System; 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.Threading; using System.Windows; using System.Windows.Controls.Primitives; using System.Windows.Threading; @@ -28,7 +28,7 @@ { public class MainWindowViewModel : BindableBase { - #region 变量 + #region DispatcherTimer private readonly DispatcherTimer _checkSerialPortTimer = new DispatcherTimer { @@ -45,8 +45,6 @@ Interval = TimeSpan.FromMinutes(5) }; - //计算时间 - private int _runningSeconds; //运行时间Timer private readonly DispatcherTimer _runningTimer = new DispatcherTimer @@ -54,36 +52,44 @@ Interval = TimeSpan.FromSeconds(1) }; - private bool _isResetParam; - - private readonly IEventAggregator _eventAggregator; - private readonly IApplicationDataService _soundSpeedDataService; - private readonly IDialogService _dialogService; - private readonly ISerialPortService _serialPortService; - - //加速度计下发指令Timer - private readonly DispatcherTimer _accelerometerCommandTimer = new DispatcherTimer - { - Interval = TimeSpan.FromSeconds(10) - }; - - private MainWindow _mainWindow; - private byte _devId = 0x02; - private string _locateDataDir; - private int _locateTimes; - private string _snapShotPath = string.Empty; - private ParamConfigModel _paramConfig; - //自动截屏倒计时 private readonly DispatcherTimer _snapShotTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(3) }; + #endregion + + #region 变量 + + private readonly IEventAggregator _eventAggregator; + private readonly IApplicationDataService _soundSpeedDataService; + private readonly IDialogService _dialogService; + private readonly ISerialPortService _serialPortService; + private readonly BackgroundWorker _backgroundWorker; + private readonly string _today; + private readonly string _week; + private MainWindow _mainWindow; + private bool _isResetParam; + private byte _devId = 0x02; + private string _locateDataDir; + private int _locateTimes; + private string _snapShotPath = string.Empty; + private ParamConfigModel _paramConfig; + + //计算时间 + private int _runningSeconds; + //Matlab算法 private static readonly Lazy LazyCorrelator = new Lazy(() => new CorrelatorSingle.Correlator()); + /// + /// 加速度:1 + /// 水听器:2 + /// + private int _workModel = 1; + #endregion #region VM属性 @@ -471,9 +477,13 @@ _dialogService = dialogService; _serialPortService = serialPortService; - RegisterMessage(); - - TimerTick(); + // 算法计算后台任务 + _backgroundWorker = new BackgroundWorker(); + _backgroundWorker.WorkerReportsProgress = true; + _backgroundWorker.WorkerSupportsCancellation = true; + _backgroundWorker.DoWork += Worker_OnDoWork; + _backgroundWorker.ProgressChanged += Worker_OnProgressChanged; + _backgroundWorker.RunWorkerCompleted += Worker_OnRunWorkerCompleted; _pipeMaterialsArray = new ObservableCollection(); var pipeMaterials = dataService.GetPipeMaterial(); @@ -482,6 +492,14 @@ PipeMaterialsArray.Add(material.ChineseMaterial); } + //获取当前日期,星期 + _today = DateTime.Now.ToString("yyyy年MM月dd日"); + _week = DateTime.Now.ToString("dddd", new CultureInfo("zh-cn")); + + RegisterMessage(); + + TimerTick(); + InitDelegateCommand(); } @@ -567,13 +585,6 @@ DialogHub.Get.ShowLoadingDialog(_mainWindow, "数据计算中,请稍后..."); //开始计算就不收集收据了且不能点击开始按钮 StartButtonEnabled = false; - RuntimeCache.CanCollectData = false; - if (!RuntimeCache.IsHydrophone) - { - //开始计算停止收集指令 - _accelerometerCommandTimer.Stop(); - } - using (var manager = new DataBaseManager()) { var today = DateTime.Now.ToString("yyyyMMdd"); @@ -594,100 +605,22 @@ } //计算 - new Thread(CalculateData).Start(); - } - - /// - /// 算法计算 - /// - private void CalculateData() - { var dataModel = RuntimeCache.CorrelatorData; - if (dataModel.LeftDeviceDataArray != null && dataModel.RightDeviceDataArray != null) + if (dataModel.LeftDeviceDataArray == null || dataModel.RightDeviceDataArray == null) { - try - { - "MainWindowViewModel".WriteLog("开始计算"); - var array = LazyCorrelator.Value.locating( - 11, - (MWNumericArray)dataModel.LeftDeviceDataArray, (MWNumericArray)dataModel.RightDeviceDataArray, - RuntimeCache.AudioSampleRate, - 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) - ); - "MainWindowViewModel".WriteLog("计算结束"); - DialogHub.Get.DismissLoadingDialog(); - - //数据绑定 - 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"; - - //设置噪声值 - CorrelatorData = dataModel; - - _eventAggregator.GetEvent().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(dataModel); - "MainWindowViewModel".WriteLog("定位数据路径:" + fileName); - - //保存了数据之后3s再截图 - _snapShotPath = $"{_locateDataDir}\\快照.{_locateTimes}.{time}.png"; - _snapShotTimer.Start(); - - _runningTimer.Stop(); - StartButtonEnabled = true; - ResetCache(); - } - 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; - ResetCache(); - } - ); - }); - } + "MainWindowViewModel".WriteLog("数据未收集完整,请稍后..."); + return; } + + if (_backgroundWorker.IsBusy) + { + "MainWindowViewModel".WriteLog("正在计算中,请稍后..."); + return; + } + + //设置噪声值 + CorrelatorData = dataModel; + _backgroundWorker.RunWorkerAsync(); } /// @@ -706,8 +639,9 @@ _serialPortService.Sp.DataBits = 8; //数据位 _serialPortService.Sp.StopBits = (StopBits)1; //停止位 _serialPortService.Sp.Open(); //打开串口 - Console.WriteLine(@"MainWindowViewModel => 打开串口"); + "MainWindowViewModel".WriteLog("打开串口"); + ConnectColorBrush = "LimeGreen"; break; } @@ -736,7 +670,10 @@ _checkSerialPortTimer.Start(); //实时显示时间 - _timer.Tick += RealTime; + _timer.Tick += delegate + { + CurrentTime = $"{_today}" + $"\x20\x20\x20{_week}\x20\x20" + DateTime.Now.ToString("HH:mm:ss"); + }; _timer.Start(); //获取电池电量 @@ -758,16 +695,6 @@ ElapseTime = _runningSeconds.ToString(); }; - //加速度计下发指令Timer - _accelerometerCommandTimer.Tick += delegate - { - if (RuntimeCache.CanCollectData) - { - RuntimeCache.IsDetectNoise = false; - CommandSender.SendCorrelatorWakeUpCmd(_serialPortService.Sp); - } - }; - //自动截屏Timer _snapShotTimer.Tick += delegate { @@ -789,7 +716,7 @@ WindowLoadedCommand = new DelegateCommand(it => { _mainWindow = it; - Console.WriteLine(@"MainWindowViewModel => 加载"); + "MainWindowViewModel".WriteLog("加载"); it.AccelerationRadioButton.Checked += delegate { RuntimeCache.IsHydrophone = false; @@ -806,9 +733,7 @@ //退出应用 CloseWindowCommand = new DelegateCommand(delegate { - _dialogService.ShowDialog( - "AlertControlDialog", - new DialogParameters + _dialogService.ShowDialog("AlertControlDialog", new DialogParameters { { "AlertType", AlertType.Question }, { "Title", "温馨提示" }, { "Message", "是否确定退出应用?" } }, @@ -1013,16 +938,11 @@ //每次计算之前都需要判断是否已经完成之前的计算,然后清空上一次的计算数据 ResetParam(); - RuntimeCache.CanCollectData = true; //开始数据采集 - if (RuntimeCache.IsHydrophone) - { - CommandSender.SendHydrophoneWakeUpCmd(_serialPortService.Sp); - } - else - { - _accelerometerCommandTimer.Start(); - } + _workModel = RuntimeCache.IsHydrophone ? 2 : 1; + "MainWindowViewModel".WriteLog("工作模式:" + _workModel); + RuntimeCache.IsDetectNoise = false; + CommandSender.SendCorrelatorWakeUpCmd(_serialPortService.Sp); //记录计算时间 _runningTimer.Start(); @@ -1062,28 +982,19 @@ _runningTimer.Stop(); _eventAggregator.GetEvent().Publish(); - - if (!RuntimeCache.IsHydrophone) - { - _accelerometerCommandTimer.Stop(); - } - - RuntimeCache.CanCollectData = false; } /// - /// 重置上次计算的缓存 + /// 清空上次计算的缓存 /// - private void ResetCache() + private void ClearCache() { RuntimeCache.RedSensorOriginalResp.Clear(); RuntimeCache.BlueSensorOriginalResp.Clear(); RuntimeCache.RedSensorResponseTags.Clear(); RuntimeCache.BlueSensorResponseTags.Clear(); - RuntimeCache.RedSensorIsEnable = false; - RuntimeCache.BlueSensorIsEnable = false; } - + /// /// 参数检查 /// @@ -1144,7 +1055,6 @@ } } - //声速 var soundVelocity = _soundSpeedDataService.GetSoundVelocity(_materialName, Convert.ToInt32(_pipeDiameter)); SoundSpeed = soundVelocity.ToString(); @@ -1152,41 +1062,101 @@ } /// - /// 实时显示时间,并监听串口状态 + /// 后台计算 /// /// - /// - private void RealTime(object sender, EventArgs args) + /// + private void Worker_OnDoWork(object sender, DoWorkEventArgs e) { - var dateTime = DateTime.Now; - var strDateTime = dateTime.ToString("yyyy年MM月dd日") + - dateTime.ToString("\0 \0 \0 dddd \0 \0 \0", new CultureInfo("zh-cn")) + - dateTime.ToString("HH:mm:ss"); - Application.Current.Dispatcher.Invoke(delegate + try { - CurrentTime = strDateTime; + "MainWindowViewModel".WriteLog("开始计算"); + var array = LazyCorrelator.Value.locating( + 11, + (MWNumericArray)_correlatorData.LeftDeviceDataArray, + (MWNumericArray)_correlatorData.RightDeviceDataArray, + RuntimeCache.AudioSampleRate, + 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), + _workModel + ); + e.Result = array; + } + catch (Exception) + { + _runningTimer.Stop(); + DialogHub.Get.DismissLoadingDialog(); - //同时监听串口状态 - if (_serialPortService.Sp.IsOpen) + Application.Current.Dispatcher.Invoke(delegate { - ConnectColorBrush = "LimeGreen"; - } - else - { - ConnectColorBrush = "LightGray"; + _dialogService.ShowDialog("AlertControlDialog", new DialogParameters + { + { "AlertType", AlertType.Question }, { "Title", "温馨提示" }, { "Message", "计算出现错误,请重新计算" } + }, + delegate(IDialogResult dialogResult) + { + if (dialogResult.Result == ButtonResult.Cancel) + { + return; + } - RedTransmitterBattery = 0; - RedTransmitterSignal = 0; - RedTransmitterState = false; + StartButtonEnabled = true; + ClearCache(); + } + ); + }); + } + } - BlueTransmitterBattery = 0; - BlueTransmitterSignal = 0; - BlueTransmitterState = false; + private void Worker_OnProgressChanged(object sender, ProgressChangedEventArgs e) + { + } - RuntimeCache.RedSensorIsEnable = false; - RuntimeCache.BlueSensorIsEnable = false; - } - }); + 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().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; + ClearCache(); } /// diff --git a/Correlator/Views/MainWindow.xaml.cs b/Correlator/Views/MainWindow.xaml.cs index 57a2282..6988e75 100644 --- a/Correlator/Views/MainWindow.xaml.cs +++ b/Correlator/Views/MainWindow.xaml.cs @@ -82,7 +82,7 @@ { Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(delegate { - "MainWindow".WriteLog("开始渲染波形图"); + "MainWindow".WriteLog("开始渲染计算结果"); //最大相关系数 var maxCorrelationCoefficient = Convert.ToDouble(array[3].ToString()); //柱状图横坐标集合