public double calcActivenessFromBufferedUsingLastData(int indexLastTo) { //仕様書p20の3 ③バッファ2の平均値を飛行機の高さに使用 ///バッファ2をAnalyseHelper.movingAverage(filteredL, filteredL.Length - 1)を使って平均化した値が飛行機の位置Yになります。 double activeness = double.NaN; if (buffer2.Count > 0) { if (buffer2.Count >= indexLastTo) { activeness = AnalyseHelper.Average(buffer2.ToArray(), buffer2.Count - indexLastTo, buffer2.Count - 1); } else { activeness = AnalyseHelper.Average(buffer2.ToArray(), 0, buffer2.Count - 1); } } if (!isstoredActiveness) { return(activeness); } //activenesses.Add(activeness);// 呼び出し毎にログ取ってるけどいいのかなぁ… return(activeness); }
static double sd(double[] numArray) { double mean = AnalyseHelper.Average(numArray, 0, numArray.Length); double n = 0.0; for (int i = 0; i < numArray.Length; i++) { //next = numArray[i] + System.Math.Pow(next - mean, 2.0); n = n + System.Math.Pow(numArray[i] - mean, 2.0); } return(System.Math.Sqrt(n / numArray.Length)); }
public double calcActivenessFromBuffered(int startIdx) { //仕様書p20の3 ③バッファ2の平均値を飛行機の高さに使用 ///バッファ2をAnalyseHelper.movingAverage(filteredL, filteredL.Length - 1)を使って平均化した値が飛行機の位置Yになります。 double activeness = 0; if (buffer2.Count > 0) { //平均値 activeness = AnalyseHelper.Average(buffer2.ToArray(), startIdx, buffer2.Count - 1); } if (!isstoredActiveness) { return(activeness); } //activenesses.Add(activeness);// 呼び出し毎にログ取ってるけどいいのかなぁ… return(activeness); }
/** * isupdateActivenessesを管理するメソッド * ・心拍数が40~180の範囲を超えている状態が5秒続いたら、画面の色更新を止めます * ・心拍数が40~180の範囲に入っている状態が3秒続いたら、画面の色更新をします * * * Revised conditions * sample num: 20 * * 1. HbT 3cm: abs(median - mean)<3 * 2. HbT 3cm: non zero * 3. Hb 1cm: median(v-v(1))<0.3 * 4. Gyro-Z: median(v-v(1))<7 * */ static void updateActivenesses() { if (Hot2gApplication.Instance.datastore.stability.Count <= 0) { return; } List <double> brain1 = Hot2gApplication.Instance.datastore.l1Ac; List <double> brain3 = Hot2gApplication.Instance.datastore.l3Ac; List <double> gyroZ = Hot2gApplication.Instance.datastore.gyroZ; GyroScope.Stability stability = Hot2gApplication.Instance.datastore.stability[Hot2gApplication.Instance.datastore.stability.Count - 1]; //Debug.Log("HRTEST State:" + sF(NpodApplication.app.state.toString()) + " / State2:" + sF(NpodApplication.app.state2.toString())) int sz = 20; if (brain1.Count > sz) { bool lastStatus = isupdateActivenesses; bool cndStability = (stability == GyroScope.Stability.Stabled); //true;//stability.isStable; // 1. HbT 3cm: abs(median - mean)<3 // val cnd1 = (median(brain3.takeLast(sz)) - brain3.takeLast(sz).average()).absoluteValue < 3.0 double B3_median = median(takeLast(brain3, sz)); double B3_ave = AnalyseHelper.Average(brain3, brain3.Count - sz, brain3.Count); bool cnd1 = (Math.Abs(B3_median - B3_ave) < 3); // 2. HbT 3cm: non zero //val cnd2 = (median(brain3.takeLast(sz)) - brain3.takeLast(sz).average()).absoluteValue != 0.0 bool cnd2 = (Math.Abs(B3_median - B3_ave) != 0.0); // 3. Hb 1cm: median(v-v(1))<0.3 bool cnd3 = median(subtract(takeLast(brain1, sz), brain1[brain1.Count - sz])) < 0.3; // 4. Gyro-Z: median(v-v(1))<7 bool cnd4 = median(subtract(takeLast(gyroZ, sz), gyroZ[gyroZ.Count - sz])) < 7; // 5. 置いたままの状態を加速度から検出 bool cnd5 = sd(takeLast(gyroZ, sz)) > 0.02; isupdateActivenessesBuffer.Add(cndStability && cnd1 && cnd2 && cnd3 && cnd4 && cnd5); if (isupdateActivenessesBuffer.Count > 50) { isupdateActivenessesBuffer.RemoveAt(0); } //isupdateActivenesses = !isupdateActivenessesBuffer.takeLast(2).all { !it } if (isupdateActivenessesBuffer.Count == 1) { isupdateActivenesses = isupdateActivenessesBuffer[0]; } else { int c = isupdateActivenessesBuffer.Count - 1; isupdateActivenesses = (isupdateActivenessesBuffer[c] || isupdateActivenessesBuffer[c - 1]); } Debug.Log("HRTEST 1:" + cnd1 + " 2:" + cnd2 + " 3:" + cnd3 + " 4:" + cnd4 + " 5:" + cnd5); if (!isupdateActivenesses) /** 非装着検出! */ { /** 計測中(装着) → 非装着 */ if (Hot2gApplication.Instance.mode == Hot2gApplication.eMode.RecieveData) { Hot2gApplication.Instance.setStateToResetGain(); //- リセット後はルーチン内でWaitingに設定される Hot2gApplication.Instance.setState2ToNotOnHead(); } else if (Hot2gApplication.Instance.mode == Hot2gApplication.eMode.Waiting) { /** 非装着中 */ //Hot2gApplication.Instance.setStateToWating(); //Hot2gApplication.Instance.setState2ToNotOnHead(); } } else { if (Hot2gApplication.Instance.mode == Hot2gApplication.eMode.Waiting) /** 装着中検出 */ { /** 非装着 → 装着 */ Hot2gApplication.Instance.setStateToMGC(); Hot2gApplication.Instance.setState2ToOnHead(); } else { /** 装着中 */ Hot2gApplication.Instance.setState2ToOnHead(); } } #if false if (!isupdateActivenesses) { /** 装着 → 非装着 */ if (lastStatus) { Hot2gApplication.Instance.setStateToResetGain(); Hot2gApplication.Instance.setState2ToNotOnHead(); } else { /** 非装着中 */ Hot2gApplication.Instance.setStateToWating(); Hot2gApplication.Instance.setState2ToNotOnHead(); } } else if (!lastStatus) { /** 非装着 → 装着 */ Hot2gApplication.Instance.setStateToMGC(); Hot2gApplication.Instance.setState2ToOnHead(); } else { /** 装着中 */ Hot2gApplication.Instance.setState2ToOnHead(); } #endif } #if false /* * var heartRate = NpodApplication.app.dataStore.heartRate * * if (heartRate.takeLast(30).all { 40 <= it && it <= 180 }) { * isupdateActivenesses = true * } * if (heartRate.takeLast(50).all { it < 40 || 180 < it }) { * isupdateActivenesses = false * } */ List <double> pulseCoef = Hot2gApplication.Instance.datastore.pulseAmplitudeCoeff; List <double> brain1 = Hot2gApplication.Instance.datastore.l1Ac; List <double> brain3 = Hot2gApplication.Instance.datastore.l3Ac; Debug.Log("HRTEST\n" + pulseCoef.Count + "," + Hot2gApplication.Instance.mode.ToString()); int sz = 20; if (pulseCoef.Count > sz) { List <double> takeLast_sz = new List <double>(); List <double> takeLast_sz_brain1 = new List <double>(); List <double> takeLast_sz_brain3 = new List <double>(); for (int i = pulseCoef.Count - 20; i < pulseCoef.Count; i++) { takeLast_sz.Add(pulseCoef[i]); takeLast_sz_brain1.Add(brain1[i]); takeLast_sz_brain3.Add(brain3[i]); } bool lastStatus = isupdateActivenesses; bool cond3 = false; double c3buf = sd(takeLast_sz.ToArray()); if (2 <= c3buf && c3buf <= 1000) { cond3 = true; } Debug.Log("c3buf " + c3buf); bool cond4 = (brain1[brain1.Count - 1] != double.NaN && brain3[brain3.Count - 1] != double.NaN); bool cond5 = max(takeLast_sz_brain1) < 30.0 && max(takeLast_sz_brain3) < 30.0; //bool cond6 = (brain1[brain1.Count - 1] != 0.0 && brain3[brain3.Count - 1] != 0.0); bool cond6 = true; Debug.Log("HRTEST 3:" + cond3 + " 4:" + cond4 + " 5:" + cond5 + " 6:" + cond6); isupdateActivenesses = cond3 && cond4 && cond5 && cond6; /** 非装着時はStateをWatingにキープ */ if (!isupdateActivenesses) { Debug.Log("NotOnHead"); Hot2gApplication.Instance.setStateToWating(); Hot2gApplication.Instance.setState2ToNotOnHead(); } /** 非装着 → 装着 */ if (isupdateActivenesses && !lastStatus) { Debug.Log("Not To OnHead"); Hot2gApplication.Instance.setStateToMGC(); Hot2gApplication.Instance.setState2ToOnHead(); } /** 装着 → 非装着 */ if (!isupdateActivenesses && lastStatus) { Debug.Log("OnHead To Not"); Hot2gApplication.Instance.setStateToResetGain(); Hot2gApplication.Instance.setState2ToNotOnHead(); } } #endif }