About Store Forum Documentation Contact



Post Reply 
Step counter for mobile platforms
Author Message
yvanvds Offline
Member

Post: #1
Step counter for mobile platforms
I thought I'd share this code. It's a simple step-counter for mobile devices. I don't suppose Esenthel will be used any time soon to make a 'personal health assistant', but it might be useful for interaction. I'm using it to make decisions based on whether the user is walking or not.

cheers,

yvan

PHP Code:
class stepDetector
{
   
void activate()
   {
      
int h = 480;
      
offset = h * 0.5f;
      
scale = - (h * 0.5f * (1.0f / (MAGNETIC_FIELD_EARTH_MAX)));
      
      
MagnetometerRefresh();
   }
   
   
void deactivate()
   {
      
MagnetometerDisable();
   }
   
   
void sensitivity(float value) // lower is more sensitive, default is 3
   
{
      
limit = value;
   }
   
   
bool update()
   {
      
bool result = false;
      
      
// Device rotation also cause acceleration. To counter
      // this, rotation is measured with the magnetometer.      
      
Vec magValue = Magnetometer();
      
      
// Distance compared to the previous update
      
magDist[magDistPtr] = Dist(magValue, lastMagValue);
      
lastMagValue = magValue;
      
      
// When 5 point average > 0.6 or current value > 1,
      // the device is rotated.
      
if(getMagAverage() > 0.6 || magDist[magDistPtr] > 1.0)
      {
         
magDistPtr++;
         if(
magDistPtr == 5) magDistPtr = 0;
         return 
result;
      }
      
      
magDistPtr++;
      if(
magDistPtr == 5) magDistPtr = 0;
      
      
// To avoid double triggers, a sleep period of 0.3 seconds
      // is added after a step
      
if(sleep > 0)
      {
         
sleep -= Time.ad();
         return 
result;
      }
      
      
// don't do anything if the value hasn't changed
      
Vec accValue = Accelerometer();
      if(
accValue != lastAccValue)
      {
         
// this part is based on code found at:
         // https://github.com/bagilevi/android-pedometer/blob/master/src/name/bagi/levente/pedometer/StepDetector.java
         
         
lastAccValue = accValue;
         
         
float calc = 0;
         
calc += offset + accValue.x * scale;
         
calc += offset + accValue.y * scale;
         
calc += offset + accValue.z * scale;         
         
calc /= 3;
         
         
// if the movement direction has changed, this is a strong indication
         // of a step occurance
         
int direction = (calc > lastCalc ?  1 : (calc < lastCalc ?  -1 : 0)); 
         if(
direction == -lastDirection)
         {
            
// direction changed
            
int extType = (direction > 0 ?  0 :  1); // minimum or maximum?
            
lastExtremes[extType] = lastCalc;
            
float diff = Abs(lastExtremes[extType] - lastExtremes[1 - extType]);
            
            if(
diff > limit)
            {
               
bool isAlmostAsLargeAsPrevious = diff > (lastDiff * 2 / 3);
               
bool isPreviousLargeEnough = lastDiff > (diff / 3);
               
bool isNotContra = (lastMatch != 1 - extType);
               
               if(
isAlmostAsLargeAsPrevious && isPreviousLargeEnough && isNotContra)
               {
                  
// this counts as a step. Sleep for 0.3 seconds
                  
result = true;
                  
lastMatch = extType;
                  
sleep = 0.3;
                  
               } else
               {
                  
lastMatch = -1;
               }
            }
            
lastDiff = diff;
         }
         
         
lastDirection = direction;
         
lastCalc = calc;
      }
      return 
result;
   }
   
   
// Helper function to get an average magnetometer value
   
float getMagAverage()
   {
      
float result = 0;
      for(
int i = 0;  i < 5; i++)
      {
         
result += magDist[i];
      }
      
      
result /= 10;
      return 
result;
   }
   

private:

   
C float MAGNETIC_FIELD_EARTH_MAX = 60.f;
   
   
// for accelerometer calculations
   
float limit = 3;
   
float lastCalc, lastDiff, scale, offset;
   
float lastExtremes[2];
   
   
int lastDirection ;
   
int lastMatch = -1;
   
   
Vec lastAccValue(0);
   
   
// for magnetometer calculations
   
Vec   lastMagValue(0);
   
float magDist     [5];
   
int   magDistPtr = 0 ; 
   
   
float sleep = 0;
}

stepDetector StepDetector; 
08-24-2015 02:27 PM
Find all posts by this user Quote this message in a reply
Pixel Perfect Offline
Member

Post: #2
RE: Step counter for mobile platforms
I'm not sure I'll ever use this but interesting none the less! Thanks for sharing smile
08-25-2015 08:22 AM
Find all posts by this user Quote this message in a reply
Post Reply