private static extern Int32 ucr_query(double[] q, Int32 m, double r, double[] buffer, Int32 buflen, ref ucr_index result);
// Do some live capturing in here... private void mWorker_GetSeries(object sender, DoWorkEventArgs e) { const int windowSize = 400; List<Tuple<double,double>> y = new List<Tuple<double, double>>(windowSize); mSerialPort.DiscardInBuffer(); while (!mTestWorker.CancellationPending) { GetSerialData(ref y); // continue if not enough input data sampled... if (y.Count < windowSize) continue; // resize captured data to windowSize - default nothing should be removed... //y.RemoveRange(windowSize, y.Count - windowSize); var minValue = double.MaxValue; Int64 ValXIndex = 0; Int64 ValYIndex = 0; string Pattern = ""; double[] bufX = y.Select(x => x.Item1).ToArray(); double[] bufY = y.Select(x => x.Item2).ToArray(); ucr_index resultX = new ucr_index(); ucr_index resultY = new ucr_index(); // apply recorded series to all trained foreach (var item in mTrainedSeries) { // compare each trained sequence with currently captured one - X values only atm double[] trainedX = item.Value.Select(x => x.Item1).ToArray(); double[] trainedY = item.Value.Select(x => x.Item2).ToArray(); // compare x and y signals if ((ucr_query(trainedX, trainedX.Length, 0.5, bufX, bufX.Length, ref resultX) < 0) /*|| (ucr_query(trainedY, trainedY.Length, 0.5, bufY, bufY.Length, ref resultY) < 0)*/) { continue; } double result = resultX.value + resultY.value; if (result < minValue) { minValue = result; ValXIndex = resultX.index; ValYIndex = resultY.index; Pattern = item.Key; } } if (minValue < 3.0) { mDispatcher.Invoke(() => { TimerLabel.Content = Pattern + " DETECTED" + "\nCost: " + minValue; if (Pattern == "Serie #0") { DetectionLight1.Fill = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(0x00, 0xFF, 0x00)); } else if (Pattern == "Serie #1") { DetectionLight2.Fill = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(0x00, 0xFF, 0x00)); } else if (Pattern == "Serie #2") { DetectionLight3.Fill = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(0x00, 0xFF, 0x00)); } else { DetectionLightx.Fill = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(0x00, 0xFF, 0x00)); } }); // clear found pattern from sampled signal to ensure that it is only detected once int cnt = mTrainedSeries[Pattern].Count; int start = (int)Math.Min(ValXIndex, ValYIndex); for (int i = start; i < start + cnt; i++) { y[i] = y[start]; } //y.RemoveRange(start, cnt); //y.InsertRange(start, new List<Tuple<double, double>>(cnt)); } else { // print result mDispatcher.Invoke(() => { TimerLabel.Content = Pattern + "\nCost: " + minValue; DetectionLight1.Fill = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(0xFF, 0x00, 0x00)); DetectionLight2.Fill = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(0xFF, 0x00, 0x00)); DetectionLight3.Fill = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(0xFF, 0x00, 0x00)); DetectionLightx.Fill = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb(0xFF, 0x00, 0x00)); }); } //y.RemoveAt(0); y.RemoveRange(0, 50); // discard values for a half second } e.Cancel = true; }