Sunday, March 3, 2013

Is there a breath?

Now that I've discussed most of the code that collects the incoming serial data from the RMI, I want to get a bit more into the code that interprets the data. We'll now use the information gathered in the ~serialReceive task to find out more about the breathing-status of the RMI user in the ~isThereaBreath routine.

I mentioned previously that the stretch sensors aren't always 100% reliable--that is why I originally tried to use data averages to distinguish breath components.  Because of this lack of reliability, I use the six RMI sensors in tandem for greater data accuracy.

Is there a breath?


//The code below is an early version which does not include any of the data analysis related to duration.


//======================~isThereaBreath=========================//

/*

~isThereaBreath is a task that determines the likelihood of different breath components (inspiration, expiration, pause) given the data gathered from the ~serialReceive Task.

The information this task can provide is:

1. Whether breath component is currently inspiration, expiration or hold/pause
2. The confidence the task has in its determination (very confident, confident, pretty sure, less certain)
3. The total depth of the inspiration/expiration (sum of all individual changes in sensor values)
//4. The time that each breath component began and ended (in later version - will post next time!)
//5. The duration of each breath component as it is completed(in later version - will post next time!)
//6. The time since the last breath (to get a sense for the frequency of breaths) (in later version - will post next time!)
//7. The overall breath cycle - two corresponding arrays that together list the duration and breath component of each completed breath cycle (in later version - will post next time!)


*/


~isThereaBreath = Task({
   inf.do({
        if(~count0.notNil 
           && ~count1.notNil 
           && ~count2.notNil 
           && ~count3.notNil 
           && ~count4.notNil 
           && ~count5.notNil, {
   
/*
Each count value represents a conclusion about the breath-status of the RMI user based on a single sensor. If count0 = 1, ~serialReceive suggests that sensor 0 indicates a breath ~totalCount adds all of these values together to determine the likelihood of a given breath-component
*/

~totalCount = ~count0 + ~count1 + ~count2 + ~count3 + ~count4 + ~count5;

//If the total count is greater than or equal to two, an inspiration seems likely
if(~totalCount >= 2, {
  //Find the sum of the actual changes in the sensor values to further determine likelihood of inspiration
  ~totalDepthInsp
      [~depthAtZeroInspiration
        ~depthAtOneInspiration
        ~depthAtTwoInspiration
        ~depthAtThreeInspiration
        ~depthAtFourInspiration
        ~depthAtFiveInspiration].sum;
       
        //if the total depth of the inspiration is greater than five
         if(~totalDepthInsp > 5, {
             //post a 1 to indicate an inspiration
             ~breath = 1;
             "inspiration".postln;
             //If the overall depth is 5 and 5 or more of the sensors indicate a breath
             if(~totalCount >=5, {
                 "very confident".postln;//a breath is very likely
              }, {
                    //If the overall depth is 5 and 4 of the sensors indicate a breath
                      if(~totalCount == 4, {
                         "confident".postln;//an inspiration is likely
                    }, {
                       //If the overall depth is 5 and 3 of the sensors indicate a breath
                         if(~totalCount == 3, {
                          "pretty sure...".postln;//there is probably an inspiration
                           }, { 
                      //If the overall depth is 5 and 2 of the sensors indicate a breath
                        if(~totalCount == 2, {
                             "less certain".postln; //Inspiration is possible
                   });
             });
       });
  });
});
          }, {
 
//If the total count is less than or equal to negative two, an expiration seems likely
if(~totalCount <= -2, {
   
  ~totalDepthExp
      [~depthAtZeroExhalation
        ~depthAtOneExhalation
        ~depthAtTwoExhalation
        ~depthAtThreeExhalation
        ~depthAtFourExhalation
        ~depthAtFiveExhalation].sum;
       
           if(~totalDepthExp < -3, {//if the total expiration depth is less than -3
              ~breath = -1;//there is an expiration
              "expiration".postln
               if(~totalCount <= -5, {//if it's less than or equal to -5
                   "very confident".postln;//confidence is high
                    }, {
                         if(~totalCount <= -3, {//if it's less than or equal to -3
                             "confident".postln;//reasonably confident
                             }, {
                                  "less certain".postln;//otherwise it's less certain
                             });
                  });
                     }, {//if totalCount is less than or = -2, that means there is an exhalation. Otherwise:
                           ~breath = 0}); //no change
                            "hold/pause".postln;
            }); 
});
     
                                   
 //THIS ARRAY SHOWS THE BREATH COMPONENTS AS THEY HAPPEN...DOES NOT DISTINGUISH BETWEEN HOLD/PAUSE

 //put all the information in a 10-slot, constantly shifting array
    ~breathArray = ~breathArray.shift(-1);
    ~breathArray[~breathArraySize - 1] = ~breath; //put breath values into the array
    ~breathArray.postln;//post it
     });
   
  0.01.wait;
   });
});

No comments:

Post a Comment