Is there anyway possible to implement this using the accelerometer in most phones? I know it won’t be as great compared to the use of a real pedometer, but I’m okay with it as long as it can detect the movement of someone walking while holding a phone in their pocket.
I want to store each step to an integer, but I also want the game to go on in the background , even if you aren’t playing it (that or have a persistent process going on even if you have the game exited.)
@Warwick Allison probably is right: when a game is running, the GPU is fully activated and draws a lot of power - I can notice this even in my notebook: when the battery is low, running any Unity game sucks the remaining charge in few minutes.
But if you want to give it a try, you must use some simple DSP techniques to filter the signal and discard small variations. The idea is to filter the accelerometer a little - to reduce electrical noise - and subtract the average gravity value. The resultant signal will show pulses at each step. To identify these pulses, you can use a “hysteresis comparator”, a state machine that changes state at two different input levels: it goes to the “high” state when the signal crosses the high limit, and only goes to the “low” state when the signal crosses the lower limit - signals in between don’t change the comparator state; this is widely used in electronics, specially at CPU inputs to reduce noise effects.
In practical Unity terms, this would be:
var loLim = 0.005; // level to fall to the low state
var hiLim = 0.1; // level to go to high state (and detect step)
var steps = 0; // step counter - counts when comp state goes high
private var stateH = false; // comparator state
var fHigh = 10.0; // noise filter control - reduces frequencies above fHigh
private var curAcc: float = 0; // noise filter
var fLow = 0.1; // average gravity filter control - time constant about 1/fLow
private var avgAcc: float; // average gravity filter
avgAcc = Input.acceleration.magnitude; // initialize avg filter
function FixedUpdate(){
// filter input.acceleration using Lerp
curAcc = Mathf.Lerp(curAcc, Input.acceleration.magnitude, Time.deltaTime * fHigh);
avgAcc = Mathf.Lerp(avgAcc, Input.acceleration.magnitude, Time.deltaTime * fLow);
var delta = curAcc-avgAcc; // gets the acceleration pulses
if (!stateH){ // if state == low...
if (delta>hiLim){ // only goes high if input > hiLim
stateH = true;
steps++; // count step when comp goes high
}
}
else {
if (delta<loLim){ // only goes low if input < loLim
stateH = false;
}
}
}
I have no accelerometer to test this, but I hope it will work easily. You probably will have to tweak the Inspector variables - specially loLim and hiLim, since no step will be counted if they are set to bad values.