7

I'm fascinated by sensor data. I used my iPhone and an app called SensorLog to capture accelerometer data while I stand and push my legs to jump.

My goal is to use R to create a model which can identify jumps and how long I'm in the air. I'm unsure how to proceed in such a challenge. I have a timeseries with accelerometer data.

https://drive.google.com/file/d/0ByWxsCBUWbqRcGlLVTVnTnZIVVk/view?usp=sharing

Some questions:

  • How can a jump be detected in timeseries data?
  • How to identify the air time part?
  • How to train such a model?

enter image description here

Below is the R code used to create the graphs above, which is me standing and doing a simple jump.

Thanks!

# Training set
sample <- read.csv("sample-data.csv")

# Sum gravity
sample$total_gravity <- sqrt(sample$accelerometerAccelerationX^2+sample$accelerometerAccelerationY^2+sample$accelerometerAccelerationZ^2)

# Smooth our total gravity to remove noise
f <- rep(1/4,4)
sample$total_gravity_smooth <- filter(sample$total_gravity, f, sides=2)

# Removes rows with NA from smoothing
sample<-sample[!is.na(sample$total_gravity_smooth),]

#sample$test<-rollmaxr(sample$total_gravity_smooth, 10, fill = NA, align = "right")

# Plot gravity
plot(sample$total_gravity, type="l", col=grey(.2), xlab="Series", ylab="Gravity", main="Accelerometer Gravitational Force")
lines(sample$total_gravity_smooth, col="red")
stdevs <- mean(sample$total_gravity_smooth)+c(-2,-1,+1,+2)*sd(sample$total_gravity_smooth)
abline(h=stdevs)
jayelm
  • 7,236
  • 5
  • 43
  • 61
João
  • 121
  • 1
  • 6
  • Refer to the answer here. Might help! http://stackoverflow.com/questions/31010553/what-is-the-right-algorithm-to-detect-segmentations-of-a-line-chart/31013066#31013066 – Shiva Jul 03 '15 at 14:42

2 Answers2

3

This is probably less than perfect solution, but it might be enough to get you started. The first part relies on a small modification of the find_peaks function from the gazetools package.

find_maxima <- function(x, threshold)
{
  ranges <- find_peak_ranges(x, threshold)
  peaks <- NULL
  if (!is.null(ranges)) {
    for (i in 1:nrow(ranges)) {
      rnge <- ranges[i, 1]:ranges[i, 2]
      r <- x[rnge]
      peaks <- c(peaks, rnge[which(r == max(r))])
    }
  }
  peaks
}


find_minima <- function(x, threshold)
{
  ranges <- find_peak_ranges(x, threshold)
  peaks <- NULL
  if (!is.null(ranges)) {
    for (i in 1:nrow(ranges)) {
      rnge <- ranges[i, 1]:ranges[i, 2]
      r <- x[rnge]
      peaks <- c(peaks, rnge[which(r == min(r))])
    }
  }
  peaks
}

In order to get the find_maxima and find_minima functions to give us what we're looking for we are going to need to smooth the total_gravity data even further:

spline <- smooth.spline(sample$loggingSample, y = sample$total_gravity, df = 30)

Note: I 'zeroed out' total gravity (sample$total_gravity <- sample$total_gravity - 1)

Next, pull out the smoothed x and y values:

out <- as.data.frame(cbind(spline$x,spline$y))

Then find our local maxima and minima

max <- find_maxima(out$y, threshold = 0.4)
min <- find_minima(out$y, threshold = -0.4)

And then plot the data to make sure everything looks legit:

plot(out$y, type="l", col=grey(.2), xlab="Series", ylab="Gravity", main="Accelerometer Gravitational Force")
lines(out$y, col="red")
stdevs <- mean(out$y)+c(-2,-1,+1,+2)*sd(out$y)
abline(h=stdevs)
abline(v=max[1], col = 'green')
abline(v=max[2], col = 'green')
abline(v=min[1], col = 'blue')

I want to be like Mike

And finally, we can see how long you were off the ground.

print(hangtime <- min[1] - max[1])
[1] 20

You can reduce your thresholds to get additional datapoints (changes in acceleration).

Hope this helps!

scribbles
  • 4,089
  • 7
  • 22
  • 29
0

I would consider a few things:

  1. Smooth the data by collecting median values every 100ms - accelerometer data on iPhones is not perfectly accurate, so this approach will help.
  2. Identify turningpoints as @scribbles suggests.

There is code available in my github repository that could be modified to help with both of these issues. A PDF with some explanation is here: https://github.com/MonteShaffer/mPowerEI/blob/master/mPowerEI/example/challenge-1a.pdf

Specifically, take a look at:

library(devtools);  
install_github("MonteShaffer/mPowerEI", subdir="mPowerEI");
library(mPowerEI);

# data smoothing
?scaleToTimeIncrement

# turning points
?pastecs::turnpoints
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
mshaffer
  • 959
  • 1
  • 9
  • 19