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