Ejemplo n.º 1
0
    void OnMeasureDataEvent(Hot2gEnumerations.EnumHot2gMeasResult e, object meas_data, string device_address)
    {
        //- 注意:3種類のBLEパケットが来るのでここは21Hzくらい。10Hz(Ac1) ,10Hz(Gyro), 1Hz(HR)...

        Debug.Log("1===:" + e + "::" + this.m_Mode);

        if (this.m_Mode == eMode.GainSetting)
        {
            /* 手動ゲイン調整 */
            adjustGain(m_nfb, m_gc, e, meas_data, m_Logger);//- -> State will change to RecieveData after this.
        }
        else if (this.m_Mode == eMode.RecieveData)
        {
            /* データ受信 */
            receiveData(m_nfb, e, meas_data, m_Logger);
        }
        else if (this.m_Mode == eMode.ResetGain)
        {
            /* ゲインリセット */
            resetGain(m_nfb, m_gc); //- -> State will change to Waiting after this.
        }
        else if (this.m_Mode == eMode.Waiting)
        {
            /* データ受信 */
            receiveData(m_nfb, e, meas_data, m_Logger);
        }


        //- Check status
        GyroScope.Stability st_stability = this.dataStore.stability[this.dataStore.stability.Count - 1];

        Debug.Log("Check2  " + "stability: " + st_stability.ToString() + " / state2:" + state2.ToString() +
                  " / mode: " + Hot2gApplication.Instance.mode.ToString());

        //- RecieveData to Waiting
        if (Hot2gApplication.Instance.mode == eMode.RecieveData)
        {
            if (st_stability != GyroScope.Stability.Stabled || state2 != eState.OnHead)
            {
                resetGain(m_nfb, m_gc);
                //GainSetDeray();
                Hot2gApplication.instance.setStateToWating();//- to Waiting
                Debug.Log("Check2  " + "GainReset!!!***************************");
            }
        }
        else if (Hot2gApplication.Instance.mode == eMode.Waiting)
        {
            if (st_stability == GyroScope.Stability.Stabled && state2 == eState.OnHead)
            {
                Hot2gApplication.instance.setStateToMGC();//- --> MGC --> RecieveData
                Debug.Log("Check2  " + "MGC Start >>>>>>>>>>>>>>>>>>>>>>>>>>");
            }
        }
    }
Ejemplo n.º 2
0
    /**
     * 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
    }
Ejemplo n.º 3
0
    /**
     * ゲイン調整済みデータ受信時の動作
     */
    private void receiveData(BrainDataFeedbacker nfb, Hot2gEnumerations.EnumHot2gMeasResult e, object data, DataLogger logger)
    {
        switch (e)
        {
        /*XB-01*/
        case Hot2gEnumerations.EnumHot2gMeasResult.Ac1ch:
            //Debug.Log("Ac1ch:" + LitJson.JsonMapper.ToJson(data));

            //- check afterGainCounter
            checkAfterGainCounter();


            if (Hot2gApplication.Instance.datastore.stability.Count > 1)
            {
                Debug.Log("Ac1chRec: [ " + Hot2gApplication.Instance.mode.ToString() +
                          " ]/[ " + Hot2gApplication.Instance.datastore.stability[Hot2gApplication.Instance.datastore.stability.Count - 1] +
                          " ]/[: " + Hot2gApplication.Instance.state2.ToString() +
                          " ]/[G1: " + Hot2gApplication.Instance.m_gc.getL1Gain() + "][G3: " + Hot2gApplication.Instance.m_gc.getL3Gain() +
                          " ]/[Raw 1: " + Hot2gApplication.Instance.datastore.l1Ac[Hot2gApplication.Instance.datastore.l1Ac.Count - 1] +
                          " ]/[Raw 3: " + Hot2gApplication.Instance.datastore.l3Ac[Hot2gApplication.Instance.datastore.l3Ac.Count - 1] +
                          " ]/ after MGC: " + Hot2gApplication.Instance.afterMGC_counter.ToString()
                          );
            }

            Xb01data xbData = this.dataStore.add(data as Hot2gMeasData1chAc, nfb.calcActivenessFromBuffered());

            state2 = updateStatusOnHead(); //- check XB-01 On head status

            nfb.bufferActiveness();        //- calc Brain activation level


            if (logger != null)
            {
                logger.write(xbData.ConvCSV());
            }

            break;

#if false
        case Hot2gEnumerations.EnumHot2gMeasResult.Ac2ch:
        {
            when(Hot2gDevInfo().valDevType)
            {
                /* HOT-2000 */
                Hot2gEnumerations.EnumHot2gDevType.HOT2000->{
                    val hot2Data = this.dataStore.add(data as Hot2gMeasData2chAc)
                                   logger?.write(hot2Data)
                }
                /* HOT-1000 */
                Hot2gEnumerations.EnumHot2gDevType.HOT1000->{
                    val hot1data = this.dataStore.add(data as Hot2gMeasData2chAc)
                                   logger?.write(hot1data)
                }
            }
#endif
        /* 心拍数 */
        case Hot2gEnumerations.EnumHot2gMeasResult.HeartRate:
            this.dataStore.add(data as Hot2gMeasDataHR);
            break;

        /* 脈波振幅関連係数 */
        case Hot2gEnumerations.EnumHot2gMeasResult.HRElement1:
            this.dataStore.add(data as Hot2gMeasDataHRElement);
            break;

        /* 姿勢変化のチェック */
        case Hot2gEnumerations.EnumHot2gMeasResult.MotionBatt:
            GyroScope.Stability s_pre = this.dataStore.stability[this.dataStore.stability.Count - 1];
            GyroScope.Stability s     = this.dataStore.add(data as Hot2gMeasDataMotBatt);
            break;
        }
    }