/* Theory: * RSD: Rapid Shake Detection * acceleration change is the sum of the delta G between consecutive samples divided * by the number of samples per second * Drastic Movement (condition1) * average acceleration change exceeds about 0.9G per sample (50ms period) * calculated over the last .75 seconds */ /// <summary> /// deltaG above 0.9G for at least .75 seconds /// </summary> /// <returns></returns> private bool condition1(gRMSAverage currentRMS) { if (!_samplesPerSecondsCalulated) { return(false); } bool bRet1 = false; //get average of values of last .75 seconds, tick diff is about 10ms between samples double sum = 0; int iSamples = 0; foreach (gRMSAverage gRMS in myAverages) { if (currentRMS.tick - gRMS.tick < 75 * 1000) //the ticks saved are milliseconds, .75seconds=75000 milliseconds { sum += gRMS.deltaG; iSamples++; } } //sum of deltas divided by samples per second double DeltaAverage = sum / _samplesPerSecond;// (iSamples * 4 / 3); Avg_deltaG_rms = DeltaAverage; //call back for information, the caller reads _Avg_deltaG_rms OnIdleDetected(new GMVector(0, 0, 0)); //how many samples exceed the Gmin treshold int iCountG = 0; foreach (GMVector g in myQueue) { if (g.Length > DeltaAverage) { iCountG++; } } //Condition1: have at least an average of 0.9G for at least .75 second if (DeltaAverage > myGmin) { if (iCountG > myTmin) { //delete all entries, RESET myQueue.Clear(); //_firstCall = true; //OnMoveDetected(gv); bRet1 = true; } } return(bRet1); }
/// <summary> /// deltaG above .5G for more than 3 seconds and /// without deltaG below .5G within last 3 seconds /// </summary> /// <param name="currentRMS"></param> /// <returns></returns> private bool condition2(gRMSAverage currentRMS, gRMSAverage lastRMS) { if (!_samplesPerSecondsCalulated) { return(false); } bool bRet = false; crossDirection crossDir = crossDirection.unknown; if (currentRMS.deltaG > myRMSmin && lastRMS.deltaG < myRMSmin) { //crossUp crossDir = crossDirection.crossUP; } else if (currentRMS.deltaG < myRMSmin && lastRMS.deltaG > myRMSmin) { //crossDown crossDir = crossDirection.crossDown; } if (myCrossDOWNs.Count > 0) { gRMSAverage lastRMSup = myCrossDOWNs.Peek(); if (crossDir == crossDirection.crossUP && (currentRMS.tick - lastRMSup.tick) >= _treshCountRMS) { if (myCrossUPs.Count > 0) { gRMSAverage lastRMSdown = myCrossDOWNs.Peek(); if ((currentRMS.tick - lastRMSdown.tick) > _treshCountRMS) { bRet = true; } } } } //enqueue current values if (crossDir == crossDirection.crossUP) { myCrossUPs.Enqueue(currentRMS); } if (crossDir == crossDirection.crossDown) { myCrossDOWNs.Enqueue(currentRMS); } return(bRet); }
public override void addValues(GMVector gv) { GMVector gvOld; if (myQueue.Count > 0)// !_firstCall) { //_samplesPerSecond= //calc samples per second if (!_samplesPerSecondsCalulated) { if (myQueue.Count > 10) { GMVector[] myQueueArray = myQueue.ToArray(); ulong iSamplesCount = 0; ulong iTickSum = 0; ulong tickDiff = 0; for (int c = myQueueArray.Length - 1; c > 1; c--) { iSamplesCount++; tickDiff = myQueueArray[c].Ticks - myQueueArray[c - 1].Ticks; iTickSum += tickDiff; } _samplesPerSecond = (uint)(1000 / (iTickSum / iSamplesCount)); // number of samples per second, ticks stored as milliseconds _samplesPerSecondsCalulated = true; } } //get and store delta gvOld = myQueue.Peek(); //calculate deltaG for current and last sample double deltaG = Math.Abs(gv.Length - gvOld.Length); //save for later use gRMSAverage currentRMS = new gRMSAverage(deltaG, gv.Ticks); myAverages.Enqueue(currentRMS); basicLogger(string.Format("{0}\t{1}\t{2}\t{3}\t{4}", gv.X, gv.Y, gv.Z, gv.Ticks, deltaG)); /* Theory: * RSD: Rapid Shake Detection * acceleration change is the sum of the delta G between consecutive samples divided * by the number of samples per second * Drastic Movement * average acceleration change exceeds about 0.9G per sample (50ms period) * calculated over the last .75 seconds * Sustained Movement * more fequently exceed an acceleration of about 0.5G (0.5G acceleration change per sample) * exceed 0.5G value within time frame for non-consecutive samples (cross counter) * time frame is set to reset after 60 non-consecutive (about 3 seconds at 50ms per sample) samples below 0.5G */ //test for condition1 bool bCondition1 = false; if (myAverages.Count > 1) { bCondition1 = condition1(currentRMS); } //test for condition2 bool bCondition2 = false; if (myAverages.Count > 1) { gRMSAverage lastRMS = myAverages.Peek(); bCondition2 = condition2(currentRMS, lastRMS); } //=============================================================================================== //start when queue is filled if (myQueue.Count >= 20) { //rapid shake detection (RSD) //Condition1: have at least an average of 0.9G for at least .75 second if (bCondition1 & bCondition2) { OnMoveDetected(gv); } }//start with filled queue } //else // _firstCall = false; myQueue.Enqueue(gv); gvOld = gv; }
public override void addValues(GMVector gv) { GMVector gvOld; if (myQueue.Count>0)// !_firstCall) { //_samplesPerSecond= //calc samples per second if (!_samplesPerSecondsCalulated) { if (myQueue.Count > 10) { GMVector[] myQueueArray = myQueue.ToArray(); ulong iSamplesCount = 0; ulong iTickSum = 0; ulong tickDiff = 0; for (int c = myQueueArray.Length - 1; c > 1; c--) { iSamplesCount++; tickDiff = myQueueArray[c].Ticks - myQueueArray[c - 1].Ticks; iTickSum += tickDiff; } _samplesPerSecond = (uint)(1000 / (iTickSum / iSamplesCount)); // number of samples per second, ticks stored as milliseconds _samplesPerSecondsCalulated = true; } } //get and store delta gvOld = myQueue.Peek(); //calculate deltaG for current and last sample double deltaG = Math.Abs(gv.Length-gvOld.Length); //save for later use gRMSAverage currentRMS=new gRMSAverage(deltaG, gv.Ticks); myAverages.Enqueue(currentRMS); basicLogger(string.Format("{0}\t{1}\t{2}\t{3}\t{4}", gv.X, gv.Y, gv.Z, gv.Ticks, deltaG)); /* Theory: * RSD: Rapid Shake Detection * acceleration change is the sum of the delta G between consecutive samples divided * by the number of samples per second * Drastic Movement * average acceleration change exceeds about 0.9G per sample (50ms period) * calculated over the last .75 seconds * Sustained Movement * more fequently exceed an acceleration of about 0.5G (0.5G acceleration change per sample) * exceed 0.5G value within time frame for non-consecutive samples (cross counter) * time frame is set to reset after 60 non-consecutive (about 3 seconds at 50ms per sample) samples below 0.5G */ //test for condition1 bool bCondition1=false; if (myAverages.Count > 1) { bCondition1 = condition1(currentRMS); } //test for condition2 bool bCondition2=false; if (myAverages.Count > 1) { gRMSAverage lastRMS = myAverages.Peek(); bCondition2 = condition2(currentRMS, lastRMS); } //=============================================================================================== //start when queue is filled if (myQueue.Count >= 20) { //rapid shake detection (RSD) //Condition1: have at least an average of 0.9G for at least .75 second if(bCondition1 & bCondition2) OnMoveDetected(gv); }//start with filled queue } //else // _firstCall = false; myQueue.Enqueue(gv); gvOld = gv; }
/// <summary> /// deltaG above .5G for more than 3 seconds and /// without deltaG below .5G within last 3 seconds /// </summary> /// <param name="currentRMS"></param> /// <returns></returns> private bool condition2(gRMSAverage currentRMS, gRMSAverage lastRMS){ if (!_samplesPerSecondsCalulated) return false; bool bRet = false; crossDirection crossDir = crossDirection.unknown; if (currentRMS.deltaG > myRMSmin && lastRMS.deltaG < myRMSmin) { //crossUp crossDir = crossDirection.crossUP; } else if (currentRMS.deltaG < myRMSmin && lastRMS.deltaG > myRMSmin) { //crossDown crossDir = crossDirection.crossDown; } if (myCrossDOWNs.Count > 0) { gRMSAverage lastRMSup = myCrossDOWNs.Peek(); if (crossDir == crossDirection.crossUP && (currentRMS.tick - lastRMSup.tick) >= _treshCountRMS) { if (myCrossUPs.Count > 0) { gRMSAverage lastRMSdown = myCrossDOWNs.Peek(); if ((currentRMS.tick - lastRMSdown.tick) > _treshCountRMS) bRet = true; } } } //enqueue current values if (crossDir == crossDirection.crossUP) myCrossUPs.Enqueue(currentRMS); if (crossDir == crossDirection.crossDown) myCrossDOWNs.Enqueue(currentRMS); return bRet; }
/* Theory: * RSD: Rapid Shake Detection * acceleration change is the sum of the delta G between consecutive samples divided * by the number of samples per second * Drastic Movement (condition1) * average acceleration change exceeds about 0.9G per sample (50ms period) * calculated over the last .75 seconds */ /// <summary> /// deltaG above 0.9G for at least .75 seconds /// </summary> /// <returns></returns> private bool condition1(gRMSAverage currentRMS) { if (!_samplesPerSecondsCalulated) return false; bool bRet1 = false; //get average of values of last .75 seconds, tick diff is about 10ms between samples double sum = 0; int iSamples = 0; foreach (gRMSAverage gRMS in myAverages) { if (currentRMS.tick - gRMS.tick < 75 * 1000) //the ticks saved are milliseconds, .75seconds=75000 milliseconds { sum += gRMS.deltaG; iSamples++; } } //sum of deltas divided by samples per second double DeltaAverage = sum / _samplesPerSecond;// (iSamples * 4 / 3); Avg_deltaG_rms = DeltaAverage; //call back for information, the caller reads _Avg_deltaG_rms OnIdleDetected(new GMVector(0, 0, 0)); //how many samples exceed the Gmin treshold int iCountG = 0; foreach (GMVector g in myQueue) { if (g.Length > DeltaAverage) iCountG++; } //Condition1: have at least an average of 0.9G for at least .75 second if (DeltaAverage > myGmin){ if (iCountG > myTmin) { //delete all entries, RESET myQueue.Clear(); //_firstCall = true; //OnMoveDetected(gv); bRet1 = true; } } return bRet1; }