17

I have written a simple Activity which is a SensorEventListener for Sensor.TYPE_ACCELEROMETER.

In my onSensorChanged(SensorEvent event) i just pick the values in X,Y,Z format and write them on to a file.

Added to this X,Y,Z is a label, the label is specific to the activity i am performing. so its X,Y,Z,label

Like this i obtain my activity profile. Would like to have suggestions on what operations to perform after data collection so as to remove noise and get the best data for an activity.

The main intent of this data collection is to construct a user activity detection application using neural network library (NeuroPh for Android) Link.

shridatt
  • 896
  • 4
  • 15
  • 39

3 Answers3

60

Just for fun I wrote a pedometer a few weeks ago, and it would have been able to detect the three activities that you mentioned. I'd make the following observations:

  1. In addition to Sensor.TYPE_ACCELEROMETER, Android also has Sensor.TYPE_GRAVITY and Sensor.TYPE_LINEAR_ACCELERATION. If you log the values of all three, then you notice that the values of TYPE_ACCELEROMETER are always equal to the sum of the values of TYPE_GRAVITY and TYPE_LINEAR_ACCELERATION. The onSensorChanged(…) method first gives you TYPE_ACCELEROMETER, followed by TYPE_GRAVITY and TYPE_LINEAR_ACCELERATION which are the results of its internal methodology of splitting the accelerometer readings into gravity and the acceleration that's not due to gravity. Given that you're interested in the acceleration due to activities, rather than the acceleration due to gravity, you may find TYPE_LINEAR_ACCELERATION is better for what you need.
  2. Whatever sensors you use, the X, Y, Z that you're measuring will depend on the orientation of the device. However, for detecting the activities that you mention, the result can't depend on e.g. whether the user is holding the device in a portrait or landscape position, or whether the device is flat or vertical, so the individual values of X, Y and Z won't be any use. Instead you'll have to look at the length of the vector, i.e. sqrt(XX+YY+ZZ) which is independent of the device orientation.
  3. You only need to smooth the data if you're feeding it into something which is sensitive to noise. Instead, I'd say that the data is the data, and you'll get the best results if you use mechanisms which aren't sensitive to noise and hence don't need the data to be smoothed. By definition, smoothing is discarding data. You want to design an algorithm that takes noisy data in at one end and outputs the current activity at the other end, so don't prejudge whether it's necessary to include smoothing as part of that algorithm
  4. Here is a graph of sqrt(XX+YY+ZZ) from Sensor.TYPE_ ACCELEROMETER which I recorded when I was building my pedometer. The graphs shows the readings measured when I walked for 100 steps. The green line is sqrt(XX+YY+Z*Z), the blue line is an exponentially weighted moving average of the green line which gives me the average level of the green line, and the red line shows my algorithm counting steps. I was able to count the steps just by looking for the maximum and minimums and when the green line crosses the blue line. I didn't use any smoothing or Fast Fourier Transforms. In my experience, for this sort of thing the simplest algorithms often work best, because although complex ones might work in some situations it's harder to predict how they'll behave in all situations. And robustness is a vital characteristic of any algorithm :-).

enter image description here

Stochastically
  • 7,616
  • 5
  • 30
  • 58
  • Woaahh... Great feed... Im amazed :)... Thanks for the answer! – shridatt May 14 '13 at 16:21
  • But one thing that questions me in your answer is how the algorithm be able to decide the output activity on basis of just one parameter sqrt(X^2+y^2+z^2) !? @Stochastically – shridatt May 14 '13 at 17:02
  • The walking is the regular up/down with peaks and troughs as shown. Stationary is when there's no movement at all away from the average, and hand held is when there's irregular movements that don't follow the walking pattern. In any case, if you just measure one sensor, and you don't want your results to be sensitive to how the device is being held, sqrt(X^2+Y^2+Z^2) is the only input that you can work with. To get more information you would need to use other sensors. – Stochastically May 14 '13 at 18:39
  • Hi @Stochastically could you link to your pedometer code please? – stanm87 Nov 13 '13 at 16:33
  • @stanm87 apologies, I don't have the time to answer questions here at the moment. FYI, the code was relatively simple, and was something that I built into http://stackoverflow.com/questions/1134579/smooth-gps-data/15657798#15657798 . For me it was one of those cases where the code ends up looking relatively simple, and is quite short too, but there are so many cases to consider that it ends up being non-trivial to get right. Each line needs to be thought about deeply! Anyway, good luck. – Stochastically Nov 18 '13 at 20:38
  • @ErumHannan I didn't use a low or high pass filter for the results here. If you do try and get better results like that, the details regarding what exactly gets filtered will be crucial. Good luck :-). – Stochastically Oct 17 '14 at 11:48
  • @Stochastically Hi, could you tell me how did you determine a step when looking at the maximum and minimums and when the green line crosses the blue line? Did you set a threshold value for those max / mins and decide that there's a step when reaching these values and going across the blue line? – John Dec 03 '14 at 13:33
  • @John I don't have the code to hand, but from memory, I *think* I did indeed have max/min values. The max/min values were relatively close to zero, but after a max, it needed to find the min before registering a step. Then after the min it was looking for the max, etc. – Stochastically Dec 03 '14 at 13:58
  • @Stochastically can u pls tell me how exactly i will calculate number of steps i have taken sqrt((x*x)+(y*y)+(z*z)) – Erum Feb 07 '15 at 17:29
  • @ErumHannan sqrt(X*X+Y*Y+Z*Z) is an orientation independent measure of the amount of acceleration, and it's the green line in the graph. So you need to look at that quantity and make up rules for what constitutes a step, e.g. crossing zero from negative to positive but not positive to negative because that would be double counting etc. Unfortunately I don't have the code that I used to hand. – Stochastically Feb 08 '15 at 11:44
  • Guys..I am making an app that will count user steps but I am not able to get the accurate step count by using my algorithm. Can you please suggest me something that could help me out. – Narender Tak Apr 27 '15 at 07:47
3

This sounds like an interesting problem!

Have you plotted your data against time to get a feel for it, to see what kind of noise you are dealing with, and to help decide how you might pre-process your data for input to the detector?

   ^
   |
 A |
   |
   |
   |
   |_________________>
   |     time
   |
   v

I'd start with lines for each activity:

  • |Ax + Ay + Az|
  • |Vx + Vy + Vz| (approximate by calculating area of trapezoids formed by your data points) ... etc

Maybe you can work out the orientation of the phone by attempting to detect gravity, then rotate your vectors to a 'standard' orientation (eg positive Z axis = up). If you can do that, then the different axes may become more meaningful. For example, walking (in pocket) would tend to have a velocity on the horizontal plane, which might be distinguished from walking (in hand) by motion in the vertical plane.

As for filters, if the data appears noisy, a simple starting point is to apply a moving average to smooth it. This is a common technique for sensor data in general:

https://en.wikipedia.org/wiki/Moving_average

Also, this post seems relevant to your question:

How to remove Gravity factor from Accelerometer readings in Android 3-axis accelerometer

Community
  • 1
  • 1
bsa
  • 2,671
  • 21
  • 31
1

Things Identified by me:

  1. The data has to be preprocessed as and how you need it to be, In my case i just want 3 inputs and one output
  2. The data has to be subjected to Smoothing (Five-point Smoothing or Any other technique which suites you the best) Reference. So that Noise gets filtered out (not completely though). Moving Average is one of the techniques
  3. Linearized data would be good, because you dont have any idea how the data was sampled, Use interpolation to help you in Linearizing the data
  4. Finally use FFT (Fast Fourier Transform) to extract the recipe out of the dish, that is to extract features out of your dataset!
shridatt
  • 896
  • 4
  • 15
  • 39