UNPKG

bowling-analysis-system

Version:

A comprehensive system for analyzing bowling techniques using video processing and metrics calculation

391 lines (367 loc) 8.97 kB
/** * @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 };