advlib-ble-gatt
Advanced tools
Comparing version 1.0.2 to 1.1.0
@@ -7,2 +7,3 @@ /** | ||
const dsp = require('./dsp'); | ||
const utils = require('./utils'); | ||
@@ -22,2 +23,5 @@ | ||
const CHARS_PER_SAMPLE = 4; | ||
const STANDARD_GRAVITY = 9.80665; | ||
const ISO_20816_MIN_FILTER_FREQUENCY = 10; | ||
const ISO_20816_MAX_FILTER_FREQUENCY = 1000; | ||
@@ -205,2 +209,14 @@ | ||
// Calculate velocityOverall for each axis: this is computation-intensive and | ||
// make take a non-negligible amount of time to execute, especially for long | ||
// time series and on resource-constrained computers! | ||
let velocityOverall = []; | ||
accelerationTimeSeries.forEach((samples) => { | ||
velocityOverall.push(calculateAverageVelocityOverall(samples, | ||
data.accelerationSamplingRate)); | ||
}); | ||
if(velocityOverall.every((value) => Number.isFinite(value))) { | ||
data.velocityOverall = velocityOverall; | ||
} | ||
data.accelerationTimeSeries = accelerationTimeSeries; | ||
@@ -222,4 +238,67 @@ data.acceleration = acceleration; | ||
/** | ||
* Calculate the average velocity overall from the given acceleration time | ||
* series, dividing it into subsamples. | ||
* @param {Array} samples The acceleration time series. | ||
* @param {Number} samplingRate The sampling rate of the time series. | ||
* @return {Number} The velocity overall. | ||
*/ | ||
function calculateAverageVelocityOverall(samples, samplingRate) { | ||
// Remove any DC offset from the time series samples | ||
let offsetSamples = dsp.dcOffset(samples); | ||
// Split the time series samples into up to four sets of at least 256 samples | ||
let sampleSets = dsp.createPowerOfTwoLengthSubSamples(offsetSamples, 256, 4); | ||
// Convert to m/s/s, then calculate and average the velocityOverall subsamples | ||
let velocityOverallSum = 0; | ||
sampleSets.forEach((sampleSet, index) => { | ||
sampleSet.forEach((sample, index) => { | ||
sampleSet[index] = sample * STANDARD_GRAVITY; // g to m/s/s | ||
}); | ||
velocityOverallSum += calculateVelocityOverall(sampleSet, samplingRate) || | ||
NaN; // Void the average should a calculation fail | ||
}); | ||
// Take the average of the sets | ||
return velocityOverallSum / sampleSets.length; | ||
} | ||
/** | ||
* Calculate the velocity overall from the given acceleration time series. | ||
* @param {Array} samples The acceleration time series. | ||
* @param {Number} samplingRate The sampling rate of the time series. | ||
* @return {Number} The velocity overall. | ||
*/ | ||
function calculateVelocityOverall(samples, samplingRate) { | ||
// Apply a Hann window to the time series | ||
let windowedSamples = dsp.hannWindow(samples); | ||
// Perform a FFT on the windowed samples | ||
let fft = dsp.fft(windowedSamples, samplingRate); | ||
// Abort should the FFT fail | ||
if(fft === null) { return null; } | ||
// Integrate over frequency (within filter window) to get velocities | ||
let filteredVelocities = []; | ||
for(let bin = 0; bin < fft.numberOfBins; bin++) { | ||
if((fft.frequencies[bin] >= ISO_20816_MIN_FILTER_FREQUENCY) && | ||
(fft.frequencies[bin] <= ISO_20816_MAX_FILTER_FREQUENCY)) { | ||
let velocity = fft.magnitudes[bin] / fft.frequencies[bin]; | ||
filteredVelocities.push(velocity); | ||
} | ||
} | ||
// Take the RMS of the velocities divided by the square root of the noise | ||
// bandwidth of the Hann window (1.5) to obtain velocity overall | ||
return dsp.rms(filteredVelocities) / Math.sqrt(1.5); | ||
} | ||
module.exports.process = process; | ||
module.exports.combine = combine; | ||
module.exports.supportedServiceUuids = SUPPORTED_SERVICE_UUIDS; |
@@ -18,3 +18,3 @@ { | ||
], | ||
"version": "1.0.2", | ||
"version": "1.1.0", | ||
"engines": { | ||
@@ -21,0 +21,0 @@ "node": ">=6.0.0" |
53016
12
877