@mattduffy/calories
v1.3.1
Published
A dependency-free library to estimate energy expenditure, in calories, using either Pandolf-Santee, LCDA or Metabolic Equivalent Task equations.
Maintainers
Readme
Estimating Energy Expenditure and Calories Burned
This package is a dependency-free ES module library that estimates calories burned during physical activities (walking, hiking, rucking, etc) with functions for both simple calorie estimates, and more advanced methods utilizing GPS data.
Creating accurate estimates of the number of calories burned during a physical activity period is notoriously difficult, especially when attempting to incorporate positional data. Most instances of estimating calories burned are simply calculated as an exertion effort based on body weight, time duration and a known MET (Metabolic Equivalent Task) value for a given activity. This method doesn't include positional data such as distance, velocity or elevation changes. This can be considered a simple calorie estimate.
There are several, more advanced methods for estimating calories burned that do attempt to incorporate GPS data for a richer, more nuanced estimate. This package provides more advanced functions to calculate calories burned using either the Pandolf-Santee or LCDA predictive models.
Using
npm install --save @mattduffy/caloriesimport { simpleCalories, pandolfCalories, lcdaCalories } from '@mattduffy/calories'Simple Calories
Using Metabolic Equivalent Tasks
The simple calories calculation takes 3 parameters: minutes, weights, and MET, and returns a positive floating point value. The function throws an Error if the required parameters are missing, or of the wrong type. You need to know the MET value for any specific activity you are measuring. A good list of MET values can be found at the Compendium of Physical Activities. The required body weight parameter is measured in kilograms.
// The number of minutes MET activity is performed.
// Required and must be greater than zero.
const minutes = 35
// Weights, measured in Kilograms. Body weight is
// required. If a ruck weight was carried, include
// that too. Optionally include weight of water
// carried as well.
// useful conversions:
// 1Kg == 2.2lbs or 1lbs === 0.45359Kg
// 1 fl oz of water === 1.042oz or 15.355 fl oz === 1lbs or 33.781 fl oz === 1kg
const weights = {
body: 70, // required Kg
ruck: 5, // optional Kg
water: 0, // optional Kg
}
// The MET number for a particular task. For example:
// Walking slowly: 2.0
// Walking, 3.0 mph: 3.0
// Weight lifting: 5.0
// Backpacking: 7.5 <-- Default value
// Swimming: 8.0
// Rope jumping (84/min): 10.5
// Jogging, 6.8 mph: 11.2
const MET = 7.5
const simple_calories = simpleCalories(minutes, weights, MET)
console.log(simple_calories)
// 143.381765625Advanced Calorie Predictive Models
The Pandolf-Santee Model
This method of estimating energy expenditure is based on the Pandolf-Santee equation. The required parameters include an array of GPS coordinate data, and a body weight, measured in kilograms. Additional values can be provided in the options parameter; including the weight of a ruck load, the weight of additional water carried, and the type of terrain covered. There is also an option to smooth out the GPS elevation data. If the elevation data comes from a GPS sensor (rather than a barometric pressure sensor), it can be useful to smooth out the values with a rolling average because some GPS sensors can provide pretty jittery values for this field.
The pandolfCalories() function expects the coordinates parameter to be an array of arrays with the following format: [longitude, latitude, heading, altitude (m), accuracy (m), timestamp (ms)]. In this particular implementation, the heading and accuracy fields are not currently being used. Those fields can be empty or null. The fields for longitude, latitude, altitude and timestamp must be valid, non-null values. Altitude is measured in meters and the timestamp is Javascript default milliseconds.
**Update** The Santee correction factor for including downhill (negative grade values) is now being applied when calculating the advanced estimates. This correction factor results in energy expenditure estimates that are typically about 16% - 20% higher when the GPS data contains significant amounts of downhill travel.
const cooords = [
//[gps longitude, gps latitude, heading (in deg), altitude (meters), gps accuracy (m), timestamp (ms)],
[-122.18413372578239, 37.82762389320808, 289.500900176593, 410.60703301243484, 6.935079779936697, 1781733047033],
[-122.18414765202105, 37.827625731095864, 291.71648070840496, 411.11239344626665, 6.935079779936697, 1781733048037],
[-122.1841647535281, 37.82762780033335, 286.09169894511865, 410.85964420530945, 7.091013324104003, 1781733049031],
[-122.18417633225566, 37.827625146283225, 284.4996500921467, 411.22145825996995, 7.091013324104003, 1781733050034],
...,
]
// Optional terrain characterization values include:
// Paved road / treadmill: 1.0
// Dirt path / packed trail: 1.1
// Light off-trail, grass: 1.2
// Soft sand, deep grass, loose gravel: 1.5
// Snow, heavy brush, swamp: 1.8
// To remove GPS elevation jitter, set smooth to true.
// The window size sets amount of smoothing, 5 is usually
// sufficient. If elevation data comes from a barometric
// sensor, set smooth to false.
const options = {
bodyWeightKg: 70, // Required, measured in kilograms
loadKg: 13.6, // optional, measured in kilograms
waterKg: 0, // optional, measured in kilograms
terrain: 1.1, // optional, default value = 1.1
smooth: true, // optional, smooth GSP elvation values
smoothWindow: 5, // optional, default value = 5
}
const pandolf_calories = pandofCalories(coords, options)
console.log(pandolf_calories)
// {
// totalKcal: 581.492205191523,
// totalDistanceM: 5544.758689134893,
// totalDurationSec: 3829.9640000000027,
// avgSpeedMs: 1.4477312813214143
// }The LCDA Predicitve Model
A much more recently developed predictive model for calculating energy expenditure over distance, while carrying a load is the Load Carrying Decision Aid model. LCDA is considered to be slightly more accurate than the Pandolf model at the extra expense of requiring parameters to calculate basal metabolic rate.
The coords and options parameters for lcdaCalories() are the same as for the above pandolfCalories() function. The values in the BMR parameter object are used to create a value for basal metabolic rate using the Mifflin-St Jeor equation.
const coords = [
//[gps longitude, gps latitude, heading (in deg), altitude (meters), gps accuracy (m), timestamp (ms)],
[-122.18413372578239, 37.82762389320808, 289.500900176593, 410.60703301243484, 6.935079779936697, 1781733047033],
[-122.18414765202105, 37.827625731095864, 291.71648070840496, 411.11239344626665, 6.935079779936697, 1781733048037],
[-122.1841647535281, 37.82762780033335, 286.09169894511865, 410.85964420530945, 7.091013324104003, 1781733049031],
[-122.18417633225566, 37.827625146283225, 284.4996500921467, 411.22145825996995, 7.091013324104003, 1781733050034],
]
const BMR = {
height: 162.5 // Required, measured in centimeters
weight: 70 // Required, measured in kilograms
age: 45 // Required, measured in years
sex: 'm' // Required, either 'm' or 'f'
}
const options = {
bodyWeightKg: 70, // Required, measured in kilograms
loadKg: 13.6, // optional, measured in kilograms
waterKg: 0, // optional, measured in kilograms
terrain: 1.1, // optional, default value = 1.1
smooth: true, // optional, smooth GSP elvation values
smoothWindow: 5, // optional, default value = 5
}
const lcda_calories = lcdaCalories(coords, BMR, options)
console.log(lcda_calories)
// {
// totalKcal: 590.292205191523,
// totalDistanceM: 5544.758689134893,
// totalDurationSec: 3829.9640000000027,
// avgSpeedMs: 1.4477312813214143
// }