Skip to main content

Processing of raw accelerometer data

Background
#

This article contains examples for the initial loading of raw accelerometer data to RStudio and Python. Both examples are processing a .bin file. For exporting the .bin file, see this article.

RStudio
#

Below is an example script in RStudio for importing and organising the accelerometer data.

R Script
file_path <- "export_1_acc.bin"

# Record layout (bytes)
TIMESTAMP_BYTES <- 6
AXIS_BYTES      <- 2
RECORD_SIZE     <- TIMESTAMP_BYTES + 3 * AXIS_BYTES

# ---- READ BINARY FILE ----
file_size <- file.info(file_path)$size
if (file_size %% RECORD_SIZE != 0) {
  stop("File size is not a multiple of record size.")
}
con <- file(file_path, "rb")
raw_data <- readBin(con, what = "raw", n = file_size)
close(con)

# Arrange raw bytes into records
data_matrix <- matrix(raw_data, ncol = RECORD_SIZE, byrow = TRUE)

# ---- TIMESTAMP CONVERSION ----
# Convert 6-byte big-endian timestamp (ms since Unix epoch)
convert_timestamp <- function(bytes) {
  sum(as.integer(bytes) * 256^(rev(seq_along(bytes)) - 1))
}
timestamps_numeric <- apply(data_matrix[, 1:TIMESTAMP_BYTES], 1, convert_timestamp)
timestamps <- as.POSIXct(timestamps_numeric / 1000, origin = "1970-01-01", tz = "GMT")

# ---- SENSOR AXES ----
decode_axis <- function(mat, scale = 0.0078125) {
  readBin(as.raw(t(mat)), what = "integer", size = 2, signed = TRUE, endian = "big", n = nrow(mat)) * scale
}

x <- decode_axis(data_matrix[,  7:8])
y <- decode_axis(data_matrix[,  9:10])
z <- decode_axis(data_matrix[, 11:12])

# ---- FINAL DATA FRAME ----
df_final <- data.frame(time = timestamps, x = x, y = y, z = z)
write.csv(df_final, "cleaned_data_2.csv", row.names = FALSE)

Python
#

The following Python function reads a .bin file and stores it in a NumPy array with 4 columns. Column 0 is the timestamp, and column 1-3 are x, y, z. The x, y and z must be scaled with 0.0078125 G.

Python Function
    def read_bin_file(self, filename):
        s = struct.Struct('>qhhh')
        sz = os.path.getsize(filename)
        data = numpy.zeros([int(sz/12), 4])
        i = 0
        f = open(filename, 'rb')
        while True:
            d = f.read(12)
            if len(d) == 0:
                break
            data[i, :] = s.unpack(b'\0\0' + d)
            #ts, x, y, z = s.unpack(b'\0\0' + d)
            i += 1
        return data