bowling-analysis-system
Version:
A comprehensive system for analyzing bowling techniques using video processing and metrics calculation
391 lines (367 loc) • 8.97 kB
JavaScript
/**
* @module config/MetricsDependencyMap
* @description Defines which metrics belong to which phase and their dependencies
*/
/**
* Phase One metrics - raw biomechanical metrics that don't require event knowledge
* These metrics are calculated directly from frame data
*/
const PHASE_ONE_METRICS = {
angles: [
// Combined metrics (pluralized)
'elbowFlexions',
'shoulderFlexions',
'shoulderRotations',
'hipRotations',
'kneeFlexions',
'ankleFlexions',
'wristAngles',
'armAngles',
'shoulderTilts',
'hipFlexions',
'trunkFlexions',
'trunkRotations',
'neckAngles',
'spineAngles',
// Individual metrics that don't have left/right variants
'armAngle',
'spineTwist',
'trunkLean',
'spineAngle',
'neckAngle',
'trunkFlexion',
'trunkRotation'
],
velocity: [
// Combined metrics (pluralized)
'armVelocities',
'shoulderVelocities',
'elbowVelocities',
'wristVelocities',
'hipVelocities',
'kneeVelocities',
'legVelocities',
'ankleVelocities',
'spineVelocities',
'headVelocities',
'footVelocities',
'handVelocities',
// Individual metrics that don't have left/right variants
'torsoVelocity',
'approachVelocity',
'ballVelocity',
'angularVelocity',
'rotationalVelocity'
],
position: [
// Combined position metrics (pluralized)
'footPositions',
'shoulderPositions',
'hipPositions',
'kneePositions',
'wristPositions',
'elbowPositions',
'anklePositions',
'handPositions',
// Combined measurement metrics (pluralized)
'armLengths',
'legLengths',
// Single position metrics
'headPosition',
'torsoPosition',
'nosePosition',
'centerOfMass',
'ballPosition',
'stanceWidth',
'torsoLength',
// Other measurements
'bodyHeight',
'shoulderWidth',
'hipWidth',
'armSpan'
],
acceleration: [
// Combined metrics (pluralized)
'armAccelerations',
'shoulderAccelerations',
'hipAccelerations',
'wristAccelerations',
'elbowAccelerations',
'legAccelerations',
'ankleAccelerations',
'spineAccelerations',
'headAccelerations',
'handAccelerations',
'footAccelerations',
// Individual metrics that don't have left/right variants
'torsoAcceleration',
'ballAcceleration',
'angularAcceleration'
],
balance: [
// Combined metrics (pluralized)
'posturalSways',
'centerOfPressures',
'weightDistributions',
'balanceAsymmetries',
'stabilitiesIndices',
// Stability metrics
'stabilityIndex',
'mediolateralStability',
'anteroposteriorStability',
// Dynamic balance
'dynamicBalance',
'staticBalance',
// Center of mass metrics
'centerOfMassTrajectory',
'centerOfMassStability',
// Stability metrics
'baseOfSupport',
// Body contribution
'upperBodyContribution',
'lowerBodyContribution',
// Balance asymmetry
'balanceAsymmetry',
// Center of pressure metrics
'copVelocity',
'copArea',
// Stability
'verticalStability'
],
power: [
// Combined metrics (pluralized)
'wristPowers',
'elbowPowers',
'shoulderPowers',
'hipPowers',
'kneePowers',
'anklePowers',
'jointPowers',
'energyTransfers',
'kineticEnergies',
'potentialEnergies',
'momentums',
'impulses',
// Individual power metrics
'totalBody',
'upperBody',
'lowerBody',
'momentum',
'impulse',
'kineticEnergy',
'energyTransfer'
],
rotation: [
// Combined metrics (pluralized)
'armRotations',
'shoulderRotations',
'hipRotations',
'pelvisRotations',
'trunkRotations',
'wristRotations',
'footRotations',
// Individual rotation metrics
'spineRotation',
'torsoRotation',
'pelvisRotation',
'shoulderRotation',
'armRotation'
],
timing: [
// Basic timing metrics that don't require event data
'phaseProgress',
'rhythmTiming'
]
};
/**
* Phase Two - Only key event detection
* These are the critical events needed for bowling analysis
*/
const PHASE_TWO_EVENTS = [
'releasePoint',
'frontFootLanding',
'backFootLanding'
];
/**
* Phase Two metrics - Event-specific metrics and measurements
* These metrics depend on the detected events from Phase Two
*/
const PHASE_TWO_METRICS = {
// Release-specific measurements
release: [
'releaseVelocities', // Combined metric
'releaseAngles', // Combined metric
'releaseHeights', // Combined metric
'releaseVelocity',
'releaseAngle',
'releaseHeight',
'releaseTiming',
'releaseConsistency',
'releaseBalance',
'releaseAlignment',
'releasePosition',
'releaseAcceleration',
'releasePower'
],
// Front foot landing measurements
frontFoot: [
'frontFootPositions', // Combined metric
'frontFootAngles', // Combined metric
'frontFootPosition',
'frontFootAngle',
'frontFootTiming',
'frontFootStability',
'frontFootBalance',
'frontFootOrientation',
'frontFootPlacement',
'frontFootPressure',
'frontFootTorque'
],
// Back foot landing measurements
backFoot: [
'backFootPositions', // Combined metric
'backFootAngles', // Combined metric
'backFootPosition',
'backFootAngle',
'backFootTiming',
'backFootStability',
'backFootBalance',
'backFootOrientation',
'backFootPlacement',
'backFootPressure',
'backFootTorque'
]
};
/**
* Phase Three metrics - Event-derived metrics
* These metrics are calculated based on events and metrics from Phases One and Two
* IMPORTANT: All metrics here MUST depend on event data from Phase Two
*/
const PHASE_THREE_METRICS = {
technique: [
'armAlignment',
'shoulderAlignment',
'hipAlignment',
'approachAlignment',
'releaseAlignment',
'followThroughAlignment',
'bodyPositioning',
'footPlacement',
'spineAlignment',
'balanceControl',
'armSwing',
'fluidMotion',
'overallTechnique'
],
efficiency: [
'powerTransfer',
'energyConservation',
'momentumTransfer',
'sequentialMovement',
'minimalWastedMovement',
'smoothTransitions',
'optimalTiming',
'effortDistribution',
'bodySegmentCoordination',
'overallEfficiency'
],
consistency: [
'approachConsistency',
'timingConsistency',
'releaseConsistency',
'followThroughConsistency',
'footPlacementConsistency',
'armSwingConsistency',
'balanceConsistency',
'movementRepeatability',
'overallConsistency'
],
power: [
'peakPower',
'powerGeneration',
'powerTiming',
'lowerBodyPower',
'upperBodyPower',
'corePower',
'rotationalPower',
'linearPower',
'accelerationRate',
'overallPower'
],
balance: [
// Event-specific balance metrics
'approachBalance',
'slideBalance',
'releaseBalance',
'followThroughBalance',
'phaseTransitionStability',
'balanceDuringTransition',
'overallBalance'
],
performance: [
'techniqueScore',
'efficiencyScore',
'powerScore',
'balanceScore',
'consistencyScore',
'overallPerformance'
],
timing: [
// Event-dependent timing metrics
'timingScores',
'phaseDurations',
'deliveryTimes',
'transitionTimings',
'overallTiming'
],
position: [
// Event-specific positions
'approachPosition',
'releasePosition',
'followThroughPosition'
],
rotation: [
// Event-specific rotations
'approachRotation',
'releaseRotation',
'followThroughRotation'
]
};
/**
* Utility function to check if a metric name is a combined metric (has left/right variants)
* @param {string} metricName - Metric name to check
* @returns {boolean} True if metric is a combined metric
*/
function isCombinedMetric(metricName) {
// Most combined metrics have plural names
return metricName.endsWith('s') && !metricName.endsWith('Mass');
}
/**
* Get singular form of a plural metric name
* @param {string} metricName - Plural metric name
* @returns {string} Singular metric name
*/
function getSingularMetricName(metricName) {
if (!metricName.endsWith('s')) return metricName;
if (metricName.endsWith('ies')) return metricName.slice(0, -3) + 'y';
return metricName.slice(0, -1);
}
/**
* Get plural form of a singular metric name
* @param {string} metricName - Singular metric name
* @returns {string} Plural metric name
*/
function getPluralMetricName(metricName) {
if (metricName.endsWith('s')) return metricName;
if (metricName.endsWith('y')) return metricName.slice(0, -1) + 'ies';
return metricName + 's';
}
module.exports = {
PHASE_ONE_METRICS,
PHASE_TWO_EVENTS,
PHASE_TWO_METRICS,
PHASE_THREE_METRICS,
isCombinedMetric,
getSingularMetricName,
getPluralMetricName
};