| name | niosh-lifting-calculator |
| description | NIOSH Lifting Equation calculator for manual material handling risk assessment. |
| allowed-tools | Bash(*) Read Write Edit Glob Grep WebFetch |
| metadata | {"author":"babysitter-sdk","version":"1.0.0","category":"ergonomics","backlog-id":"SK-IE-020"} |
| graph | {"domains":["domain:industrial-engineering"],"skillAreas":["skill-area:statistical-analysis","skill-area:organizational-design","skill-area:data-analysis"],"roles":["role:operations-analyst","role:research-engineer"]} |
niosh-lifting-calculator
You are niosh-lifting-calculator - a specialized skill for assessing manual lifting tasks using the NIOSH Lifting Equation.
Overview
This skill enables AI-powered lifting risk assessment including:
- Recommended Weight Limit (RWL) calculation
- Lifting Index (LI) computation
- Multiplier factor analysis (HM, VM, DM, AM, FM, CM)
- Single-task and multi-task analysis
- Risk level classification
- Work redesign recommendations
- Comparison of job modifications
Capabilities
1. NIOSH Lifting Equation
from dataclasses import dataclass
from typing import Optional
import math
@dataclass
class LiftingTaskParameters:
"""
Input parameters for NIOSH Lifting Equation
"""
load_weight_lbs: float
horizontal_origin: float
vertical_origin: float
horizontal_dest: float
vertical_dest: float
vertical_travel: float
asymmetry_angle: float
frequency: float
duration: float
coupling: str
def calculate_rwl(params: LiftingTaskParameters, at_origin: bool = True):
"""
Calculate Recommended Weight Limit using NIOSH equation
RWL = LC x HM x VM x DM x AM x FM x CM
LC = Load Constant = 51 lbs
"""
LC = 51
H = params.horizontal_origin if at_origin else params.horizontal_dest
V = params.vertical_origin if at_origin else params.vertical_dest
H = max(10, min(H, 25))
HM = 10 / H
VM = 1 - 0.0075 * abs(V - 30)
VM = max(0, VM)
D = max(10, params.vertical_travel)
DM = 0.82 + (1.8 / D)
DM = min(1, DM)
A = min(135, params.asymmetry_angle)
AM = 1 - (0.0032 * A)
FM = get_frequency_multiplier(params.frequency, params.duration, V)
CM = get_coupling_multiplier(params.coupling, V)
RWL = LC * HM * VM * DM * AM * FM * CM
return {
"RWL": round(RWL, 1),
"multipliers": {
"LC": LC,
"HM": round(HM, 3),
"VM": round(VM, 3),
"DM": round(DM, 3),
"AM": round(AM, 3),
"FM": round(FM, 3),
"CM": round(CM, 3)
},
"location": "origin" if at_origin else "destination"
}
def get_frequency_multiplier(frequency, duration, vertical):
"""
Frequency Multiplier lookup table
"""
FM_TABLE = {
(0.2, 1, True): 1.00, (0.2, 1, False): 1.00,
(0.5, 1, True): 0.97, (0.5, 1, False): 0.97,
(1, 1, True): 0.94, (1, 1, False): 0.94,
(2, 1, True): 0.91, (2, 1, False): 0.91,
(3, 1, True): 0.88, (3, 1, False): 0.88,
(4, 1, True): 0.84, (4, 1, False): 0.84,
(5, 1, True): 0.80, (5, 1, False): 0.80,
}
v_category = vertical >= 30
key = (min(15, frequency), int(duration), v_category)
if frequency <= 0.2:
return 1.0
elif frequency >= 15:
return 0.0
else:
return max(0, 1 - 0.05 * frequency)
def get_coupling_multiplier(coupling, vertical):
"""
Coupling Multiplier based on handle quality
"""
CM_TABLE = {
("good", True): 1.00,
("good", False): 1.00,
("fair", True): 0.95,
("fair", False): 1.00,
("poor", True): 0.90,
("poor", False): 0.90
}
v_category = vertical >= 30
return CM_TABLE.get((coupling.lower(), v_category), 0.90)
2. Lifting Index Calculation
def calculate_lifting_index(params: LiftingTaskParameters):
"""
Calculate Lifting Index
LI = Load Weight / RWL
LI interpretation:
- LI ≤ 1.0: Acceptable for most workers
- 1.0 < LI ≤ 3.0: Increased risk, some workers may be at risk
- LI > 3.0: Unacceptable for most workers
"""
rwl_origin = calculate_rwl(params, at_origin=True)
rwl_dest = calculate_rwl(params, at_origin=False)
rwl = min(rwl_origin['RWL'], rwl_dest['RWL'])
limiting_location = "origin" if rwl_origin['RWL'] < rwl_dest['RWL'] else "destination"
li = params.load_weight_lbs / rwl if rwl > 0 else float('inf')
if li <= 1.0:
risk_level = "LOW"
risk_description = "Task acceptable for most healthy workers"
elif li <= 2.0:
risk_level = "MODERATE"
risk_description = "Increased risk - consider job modifications"
elif li <= 3.0:
risk_level = "HIGH"
risk_description = "High risk - job redesign recommended"
else:
risk_level = "VERY HIGH"
risk_description = "Unacceptable risk - immediate redesign required"
return {
: (li, ),
: rwl,
: rwl_origin[],
: rwl_dest[],
: limiting_location,
: params.load_weight_lbs,
: risk_level,
: risk_description,
: rwl_origin[],
: rwl_dest[]
}
3. Multi-Task Analysis
def multi_task_lifting_index(tasks: list):
"""
Calculate Composite Lifting Index for multiple tasks
CLI = LI_max + sum of (LI_adjusted for remaining tasks)
"""
if not tasks:
return None
task_results = []
for task in tasks:
result = calculate_lifting_index(task['params'])
result['task_name'] = task.get('name', 'Unnamed')
result['frequency'] = task['params'].frequency
task_results.append(result)
task_results.sort(key=lambda x: x['lifting_index'], reverse=True)
cli = task_results[0]['lifting_index']
for i in range(1, len(task_results)):
freq_factor = sum(t['frequency'] for t in task_results[:i+1]) / \
sum(t['frequency'] for t in task_results[:i])
cli += task_results[i]['lifting_index'] * (freq_factor - 1) / freq_factor
return {
: (cli, ),
: task_results,
: task_results[][],
: get_risk_level(cli)
}
():
li <= :
li <= :
li <= :
:
4. Multiplier Analysis and Recommendations
def analyze_multipliers(result: dict):
"""
Identify which factors are limiting and provide recommendations
"""
multipliers = result.get('multipliers_origin', {})
limiting_factors = []
thresholds = {
"HM": 0.7,
"VM": 0.8,
"DM": 0.8,
"AM": 0.8,
"FM": 0.7,
"CM": 0.9
}
recommendations = []
for factor, threshold in thresholds.items():
if factor in multipliers and multipliers[factor] < threshold:
limiting_factors.append(factor)
if factor == "HM":
recommendations.append({
"factor": "Horizontal Distance",
"issue": f"HM = {multipliers[factor]:.2f} - load too far from body",
"recommendations": [
"Move load closer to worker",
"Use conveyors or slides",
"Eliminate obstacles between worker and load",
]
})
factor == :
recommendations.append({
: ,
: ,
: [
,
,
]
})
factor == :
recommendations.append({
: ,
: ,
: [
,
,
]
})
factor == :
recommendations.append({
: ,
: ,
: [
,
,
]
})
factor == :
recommendations.append({
: ,
: ,
: [
,
,
,
]
})
factor == :
recommendations.append({
: ,
: ,
: [
,
,
]
})
{
: limiting_factors,
: recommendations,
: limiting_factors[] limiting_factors
}
5. Job Modification Comparison
def compare_modifications(baseline: LiftingTaskParameters, modifications: list):
"""
Compare baseline to proposed modifications
"""
baseline_result = calculate_lifting_index(baseline)
comparisons = [{
"scenario": "Baseline",
"changes": None,
"lifting_index": baseline_result['lifting_index'],
"rwl": baseline_result['rwl'],
"risk_level": baseline_result['risk_level'],
"improvement": 0
}]
for mod in modifications:
mod_result = calculate_lifting_index(mod['params'])
improvement = (baseline_result['lifting_index'] - mod_result['lifting_index']) / \
baseline_result['lifting_index'] * 100
comparisons.append({
"scenario": mod['name'],
"changes": mod.get('description', ''),
"lifting_index": mod_result['lifting_index'],
"rwl": mod_result['rwl'],
"risk_level": mod_result['risk_level'],
"improvement": round(improvement, 1)
})
comparisons.sort(key=lambda x: x['lifting_index'])
return {
"comparisons": comparisons,
: comparisons[][],
: comparisons[][]
}
Process Integration
This skill integrates with the following processes:
ergonomic-risk-assessment.js
workstation-design-optimization.js
Output Format
{
"lifting_index": 1.8,
"rwl": 28.3,
"actual_weight": 51,
"risk_level": "MODERATE",
"limiting_factors": ["HM", "AM"],
"recommendations": [
{
"factor": "Horizontal Distance",
"recommendations": ["Move load closer to worker"]
}
],
"improvement_options": [
{
"scenario": "Add lift table",
"improvement": 45
}
]
}
Best Practices
- Measure accurately - Use tape measure, goniometer
- Worst case analysis - Assess most strenuous conditions
- Consider variations - Different workers, load sizes
- Multi-task jobs - Use CLI for varied tasks
- Verify after changes - Re-assess after modifications
- Document everything - Photos, measurements, observations
Constraints
- NIOSH equation has limitations (no pushing/pulling)
- Valid for two-handed lifts only
- Assumes adequate grip
- Does not account for environmental factors