bowling-analysis-system
Version:
A comprehensive system for analyzing bowling techniques using video processing and metrics calculation
567 lines (498 loc) • 24.8 kB
JavaScript
/**
* @module metrics/calculations/AccelerationCalculations
* @description Functions for calculating joint accelerations
*/
const { calculateAcceleration } = require('./MetricsUtilities');
const {
calculateRightWristVelocity,
calculateLeftWristVelocity,
calculateRightElbowVelocity,
calculateLeftElbowVelocity,
calculateRightShoulderVelocity,
calculateLeftShoulderVelocity,
calculateRightHipVelocity,
calculateLeftHipVelocity,
calculateRightKneeVelocity,
calculateLeftKneeVelocity,
calculateRightAnkleVelocity,
calculateLeftAnkleVelocity,
calculateRightArmVelocity,
calculateLeftArmVelocity,
calculateRightLegVelocity,
calculateLeftLegVelocity,
calculateWristVelocities,
calculateElbowVelocities,
calculateShoulderVelocities,
calculateHipVelocities,
calculateKneeVelocities,
calculateAnkleVelocities
} = require('./VelocityCalculations');
/**
* Calculate wrist acceleration
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {number} Wrist acceleration in units per second squared
*/
function calculateWristAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
const currentVel = calculateRightWristVelocity(currentFrame, prevFrame, timeDelta);
const prevVel = calculateRightWristVelocity(prevFrame, prevPrevFrame, timeDelta);
return calculateAcceleration(currentVel, prevVel, timeDelta);
}
/**
* Calculate left wrist acceleration
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {number} Left wrist acceleration in units per second squared
*/
function calculateLeftWristAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
const currentVel = calculateLeftWristVelocity(currentFrame, prevFrame, timeDelta);
const prevVel = calculateLeftWristVelocity(prevFrame, prevPrevFrame, timeDelta);
return calculateAcceleration(currentVel, prevVel, timeDelta);
}
/**
* Calculate elbow acceleration
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {number} Elbow acceleration in units per second squared
*/
function calculateElbowAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
const currentVel = calculateRightElbowVelocity(currentFrame, prevFrame, timeDelta);
const prevVel = calculateRightElbowVelocity(prevFrame, prevPrevFrame, timeDelta);
return calculateAcceleration(currentVel, prevVel, timeDelta);
}
/**
* Calculate left elbow acceleration
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {number} Left elbow acceleration in units per second squared
*/
function calculateLeftElbowAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
const currentVel = calculateLeftElbowVelocity(currentFrame, prevFrame, timeDelta);
const prevVel = calculateLeftElbowVelocity(prevFrame, prevPrevFrame, timeDelta);
return calculateAcceleration(currentVel, prevVel, timeDelta);
}
/**
* Calculate shoulder acceleration
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {number} Shoulder acceleration in units per second squared
*/
function calculateShoulderAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
const currentVel = calculateRightShoulderVelocity(currentFrame, prevFrame, timeDelta);
const prevVel = calculateRightShoulderVelocity(prevFrame, prevPrevFrame, timeDelta);
return calculateAcceleration(currentVel, prevVel, timeDelta);
}
/**
* Calculate left shoulder acceleration
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {number} Left shoulder acceleration in units per second squared
*/
function calculateLeftShoulderAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
const currentVel = calculateLeftShoulderVelocity(currentFrame, prevFrame, timeDelta);
const prevVel = calculateLeftShoulderVelocity(prevFrame, prevPrevFrame, timeDelta);
return calculateAcceleration(currentVel, prevVel, timeDelta);
}
/**
* Calculate hip acceleration
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {number} Hip acceleration in units per second squared
*/
function calculateHipAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
const currentVel = calculateRightHipVelocity(currentFrame, prevFrame, timeDelta);
const prevVel = calculateRightHipVelocity(prevFrame, prevPrevFrame, timeDelta);
return calculateAcceleration(currentVel, prevVel, timeDelta);
}
/**
* Calculate left hip acceleration
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {number} Left hip acceleration in units per second squared
*/
function calculateLeftHipAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
const currentVel = calculateLeftHipVelocity(currentFrame, prevFrame, timeDelta);
const prevVel = calculateLeftHipVelocity(prevFrame, prevPrevFrame, timeDelta);
return calculateAcceleration(currentVel, prevVel, timeDelta);
}
/**
* Calculate knee acceleration
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {number} Knee acceleration in units per second squared
*/
function calculateKneeAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
const currentVel = calculateRightKneeVelocity(currentFrame, prevFrame, timeDelta);
const prevVel = calculateRightKneeVelocity(prevFrame, prevPrevFrame, timeDelta);
return calculateAcceleration(currentVel, prevVel, timeDelta);
}
/**
* Calculate left knee acceleration
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {number} Left knee acceleration in units per second squared
*/
function calculateLeftKneeAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
const currentVel = calculateLeftKneeVelocity(currentFrame, prevFrame, timeDelta);
const prevVel = calculateLeftKneeVelocity(prevFrame, prevPrevFrame, timeDelta);
return calculateAcceleration(currentVel, prevVel, timeDelta);
}
/**
* Calculate ankle acceleration
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {number} Ankle acceleration in units per second squared
*/
function calculateAnkleAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
const currentVel = calculateRightAnkleVelocity(currentFrame, prevFrame, timeDelta);
const prevVel = calculateRightAnkleVelocity(prevFrame, prevPrevFrame, timeDelta);
return calculateAcceleration(currentVel, prevVel, timeDelta);
}
/**
* Calculate left ankle acceleration
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {number} Left ankle acceleration in units per second squared
*/
function calculateLeftAnkleAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
const currentVel = calculateLeftAnkleVelocity(currentFrame, prevFrame, timeDelta);
const prevVel = calculateLeftAnkleVelocity(prevFrame, prevPrevFrame, timeDelta);
return calculateAcceleration(currentVel, prevVel, timeDelta);
}
/**
* Calculate arm acceleration (combined wrist and elbow)
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {number} Arm acceleration in units per second squared
*/
function calculateArmAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
// Calculate average of wrist and elbow accelerations for arm acceleration
const wristAcc = calculateWristAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
const elbowAcc = calculateElbowAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
return (wristAcc + elbowAcc) / 2;
}
/**
* Calculate left arm acceleration (combined wrist and elbow)
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {number} Left arm acceleration in units per second squared
*/
function calculateLeftArmAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
// Calculate average of wrist and elbow accelerations for arm acceleration
const wristAcc = calculateLeftWristAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
const elbowAcc = calculateLeftElbowAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
return (wristAcc + elbowAcc) / 2;
}
/**
* Calculate leg acceleration (combined knee and ankle)
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {number} Leg acceleration in units per second squared
*/
function calculateLegAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
// Calculate average of knee and ankle accelerations for leg acceleration
const kneeAcc = calculateKneeAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
const ankleAcc = calculateAnkleAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
return (kneeAcc + ankleAcc) / 2;
}
/**
* Calculate left leg acceleration (combined knee and ankle)
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {number} Left leg acceleration in units per second squared
*/
function calculateLeftLegAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
// Calculate average of knee and ankle accelerations for leg acceleration
const kneeAcc = calculateLeftKneeAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
const ankleAcc = calculateLeftAnkleAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
return (kneeAcc + ankleAcc) / 2;
}
/**
* Calculate torso acceleration
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {number} Torso acceleration in units per second squared
*/
function calculateTorsoAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
// Use shoulder and hip accelerations to calculate torso acceleration
const shoulderAcc = calculateShoulderAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
const hipAcc = calculateHipAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
return (shoulderAcc + hipAcc) / 2;
}
/**
* Calculate head acceleration
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {number} Head acceleration in units per second squared
*/
function calculateHeadAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
// Since head velocity is not directly calculated,
// we can approximate using shoulder movement and some calculations
const { getSafeLandmark, calculateDistance } = require('./MetricsUtilities');
// Get head landmark (0) for each frame
const currentHead = getSafeLandmark(currentFrame, 0);
const prevHead = getSafeLandmark(prevFrame, 0);
const prevPrevHead = getSafeLandmark(prevPrevFrame, 0);
if (!currentHead || !prevHead || !prevPrevHead) return null;
// Calculate velocities
const currentVel = calculateDistance(currentHead, prevHead) / (timeDelta / 1000);
const prevVel = calculateDistance(prevHead, prevPrevHead) / (timeDelta / 1000);
// Calculate acceleration
return calculateAcceleration(currentVel, prevVel, timeDelta);
}
/**
* Calculate spine acceleration
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {number} Spine acceleration in units per second squared
*/
function calculateSpineAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
// Calculate midpoint between shoulders and midpoint between hips for each frame
// Then calculate acceleration of these spine points
const { getSafeLandmark, calculateDistance } = require('./MetricsUtilities');
// Get landmarks for shoulders and hips
const currentLeftShoulder = getSafeLandmark(currentFrame, 11);
const currentRightShoulder = getSafeLandmark(currentFrame, 12);
const currentLeftHip = getSafeLandmark(currentFrame, 23);
const currentRightHip = getSafeLandmark(currentFrame, 24);
const prevLeftShoulder = getSafeLandmark(prevFrame, 11);
const prevRightShoulder = getSafeLandmark(prevFrame, 12);
const prevLeftHip = getSafeLandmark(prevFrame, 23);
const prevRightHip = getSafeLandmark(prevFrame, 24);
const prevPrevLeftShoulder = getSafeLandmark(prevPrevFrame, 11);
const prevPrevRightShoulder = getSafeLandmark(prevPrevFrame, 12);
const prevPrevLeftHip = getSafeLandmark(prevPrevFrame, 23);
const prevPrevRightHip = getSafeLandmark(prevPrevFrame, 24);
if (!currentLeftShoulder || !currentRightShoulder || !currentLeftHip || !currentRightHip ||
!prevLeftShoulder || !prevRightShoulder || !prevLeftHip || !prevRightHip ||
!prevPrevLeftShoulder || !prevPrevRightShoulder || !prevPrevLeftHip || !prevPrevRightHip) {
return null;
}
// Calculate midpoints for spine
const currentSpineMid = [
(currentLeftShoulder[0] + currentRightShoulder[0] + currentLeftHip[0] + currentRightHip[0]) / 4,
(currentLeftShoulder[1] + currentRightShoulder[1] + currentLeftHip[1] + currentRightHip[1]) / 4,
(currentLeftShoulder[2] + currentRightShoulder[2] + currentLeftHip[2] + currentRightHip[2]) / 4
];
const prevSpineMid = [
(prevLeftShoulder[0] + prevRightShoulder[0] + prevLeftHip[0] + prevRightHip[0]) / 4,
(prevLeftShoulder[1] + prevRightShoulder[1] + prevLeftHip[1] + prevRightHip[1]) / 4,
(prevLeftShoulder[2] + prevRightShoulder[2] + prevLeftHip[2] + prevRightHip[2]) / 4
];
const prevPrevSpineMid = [
(prevPrevLeftShoulder[0] + prevPrevRightShoulder[0] + prevPrevLeftHip[0] + prevPrevRightHip[0]) / 4,
(prevPrevLeftShoulder[1] + prevPrevRightShoulder[1] + prevPrevLeftHip[1] + prevPrevRightHip[1]) / 4,
(prevPrevLeftShoulder[2] + prevPrevRightShoulder[2] + prevPrevLeftHip[2] + prevPrevRightHip[2]) / 4
];
// Calculate velocities
const currentVel = calculateDistance(currentSpineMid, prevSpineMid) / (timeDelta / 1000);
const prevVel = calculateDistance(prevSpineMid, prevPrevSpineMid) / (timeDelta / 1000);
// Calculate acceleration
return calculateAcceleration(currentVel, prevVel, timeDelta);
}
/**
* Calculate wrist accelerations for both left and right sides
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {Object} Object containing left and right wrist accelerations
*/
function calculateWristAccelerations(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
const rightAcc = calculateWristAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
const leftAcc = calculateLeftWristAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
return {
right: rightAcc,
left: leftAcc,
average: (rightAcc !== null && leftAcc !== null) ? (rightAcc + leftAcc) / 2 : null
};
}
/**
* Calculate elbow accelerations for both left and right sides
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {Object} Object containing left and right elbow accelerations
*/
function calculateElbowAccelerations(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
const rightAcc = calculateElbowAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
const leftAcc = calculateLeftElbowAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
return {
right: rightAcc,
left: leftAcc,
average: (rightAcc !== null && leftAcc !== null) ? (rightAcc + leftAcc) / 2 : null
};
}
/**
* Calculate shoulder accelerations for both left and right sides
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {Object} Object containing left and right shoulder accelerations
*/
function calculateShoulderAccelerations(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
const rightAcc = calculateShoulderAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
const leftAcc = calculateLeftShoulderAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
return {
right: rightAcc,
left: leftAcc,
average: (rightAcc !== null && leftAcc !== null) ? (rightAcc + leftAcc) / 2 : null
};
}
/**
* Calculate hip accelerations for both left and right sides
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {Object} Object containing left and right hip accelerations
*/
function calculateHipAccelerations(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
const rightAcc = calculateHipAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
const leftAcc = calculateLeftHipAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
return {
right: rightAcc,
left: leftAcc,
average: (rightAcc !== null && leftAcc !== null) ? (rightAcc + leftAcc) / 2 : null
};
}
/**
* Calculate knee accelerations for both left and right sides
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {Object} Object containing left and right knee accelerations
*/
function calculateKneeAccelerations(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
const rightAcc = calculateKneeAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
const leftAcc = calculateLeftKneeAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
return {
right: rightAcc,
left: leftAcc,
average: (rightAcc !== null && leftAcc !== null) ? (rightAcc + leftAcc) / 2 : null
};
}
/**
* Calculate ankle accelerations for both left and right sides
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {Object} Object containing left and right ankle accelerations
*/
function calculateAnkleAccelerations(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
const rightAcc = calculateAnkleAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
const leftAcc = calculateLeftAnkleAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
return {
right: rightAcc,
left: leftAcc,
average: (rightAcc !== null && leftAcc !== null) ? (rightAcc + leftAcc) / 2 : null
};
}
/**
* Calculate arm accelerations for both left and right sides
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {Object} Object containing left and right arm accelerations
*/
function calculateArmAccelerations(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
const rightAcc = calculateArmAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
const leftAcc = calculateLeftArmAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
return {
right: rightAcc,
left: leftAcc,
average: (rightAcc !== null && leftAcc !== null) ? (rightAcc + leftAcc) / 2 : null
};
}
/**
* Calculate leg accelerations for both left and right sides
* @param {Array} currentFrame - Current frame landmarks
* @param {Array} prevFrame - Previous frame landmarks
* @param {Array} prevPrevFrame - Frame before previous frame landmarks
* @param {number} timeDelta - Time between frames in ms
* @returns {Object} Object containing left and right leg accelerations
*/
function calculateLegAccelerations(currentFrame, prevFrame, prevPrevFrame, timeDelta) {
const rightAcc = calculateLegAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
const leftAcc = calculateLeftLegAcceleration(currentFrame, prevFrame, prevPrevFrame, timeDelta);
return {
right: rightAcc,
left: leftAcc,
average: (rightAcc !== null && leftAcc !== null) ? (rightAcc + leftAcc) / 2 : null
};
}
module.exports = {
// Combined metrics (with both left/right values)
calculateWristAccelerations,
calculateElbowAccelerations,
calculateShoulderAccelerations,
calculateHipAccelerations,
calculateKneeAccelerations,
calculateAnkleAccelerations,
calculateArmAccelerations,
calculateLegAccelerations,
// Individual metrics still exported for internal use
calculateWristAcceleration,
calculateLeftWristAcceleration,
calculateElbowAcceleration,
calculateLeftElbowAcceleration,
calculateShoulderAcceleration,
calculateLeftShoulderAcceleration,
calculateHipAcceleration,
calculateLeftHipAcceleration,
calculateKneeAcceleration,
calculateLeftKneeAcceleration,
calculateAnkleAcceleration,
calculateLeftAnkleAcceleration,
calculateArmAcceleration,
calculateLeftArmAcceleration,
calculateLegAcceleration,
calculateLeftLegAcceleration,
// Single value metrics
calculateTorsoAcceleration,
calculateHeadAcceleration,
calculateSpineAcceleration
};