Compute 3D lower-limb joint moments with inverse dynamics
Source:R/kinetics-inverse-dynamics.R
inverseDynamics3D.RdComputes ankle, knee, and hip net moment vectors in 3D from joint-center coordinates, GRF, COP, and segment inertial properties, using a recursive link-segment Newton-Euler chain (foot -> shank -> thigh).
Arguments
- joints
Matrix/data.frame with columns
ankle_x,ankle_y,ankle_z,knee_x,knee_y,knee_z,hip_x,hip_y,hip_z, and - formodel = "newton_euler"- the foot distal endtoe_x,toe_y,toe_z.- grf
Matrix/data.frame with columns
fx,fy,fzand optionalcop_x,cop_y,cop_z(and, formodel = "newton_euler", optional free momentstx,ty,tz).- sampling_rate
Sampling rate in Hz.
- angles
Optional matrix/data.frame containing 3D joint angles with columns
ankle_x,ankle_y,ankle_z,knee_x,knee_y,knee_z,hip_x,hip_y,hip_z.- angular_velocity
Optional 3D joint angular velocity table.
- angular_acceleration
Optional 3D joint angular acceleration table.
- inertial
Optional data.frame from
estimateSegmentInertia(). Required formodel = "newton_euler"unlessbody_massis given; undermodel = "quasi_static"it only supplies anI * alphacorrection and is ignored when omitted.- angle_unit
Unit of angle-related inputs:
"radian"or"degree".- model
Which dynamics model to use:
"newton_euler"(the default, the full recursive chain viainverseDynamicsRNE()) or"quasi_static"(the legacy massless-segment approximation; seeinverseDynamics2D()).- body_mass
Body mass in kg, used to build the segment inertia table with
estimateSegmentInertia()wheninertialis not supplied.- body_height
Body height in m, used when segment lengths must be estimated from stature rather than measured from the markers.
- gravity
Gravitational acceleration in m/s^2.
- vertical
Which coordinate axis points up,
"y"(default) or"z". Gravity acts along the negative of this axis, so it must match the laboratory convention ofjoints. The default follows this package's marker convention (x antero-posterior, y vertical, z medio-lateral) and the sagittalinverseDynamics2D(); note that force-plate hardware normally reports the vertical force asfz, sogrfmay need reordering to match. A mismatch is checked against the marker geometry and warned about, because the wrong axis silently removes every gravitational moment. Used only bymodel = "newton_euler"; the quasi-static model has no gravity term and therefore ignores it.
Value
A data.frame with time and moment components:
*_moment_x, *_moment_y, *_moment_z. If angular velocity is
available, *_power_total columns are included.
model = "newton_euler" also returns the proximal joint reaction force
components (ankle_fx, ankle_fy, ankle_fz, ...).
Details
See inverseDynamics2D() for what the two models compute and why the
quasi-static one is retained only for reproducibility. The 3D moment balance
uses an axisymmetric segment inertia and neglects the gyroscopic
\(\omega \times I \omega\) term and any spin about the segment long axis,
which is not observable from two joint centres.
References
Winter DA (2009). "Biomechanics and Motor Control of Human Movement." 4th ed. John Wiley & Sons.
See also
inverseDynamicsRNE() for the underlying recursion,
inverseDynamics2D() for sagittal-plane inverse dynamics,
estimateSegmentInertia() for segment inertial properties,
computeJointPower() for joint power calculation.
Examples
n <- 200
joints <- data.frame(
ankle_x = rep(0.00, n), ankle_y = rep(0.05, n), ankle_z = rep(0.00, n),
toe_x = rep(0.15, n), toe_y = rep(0.01, n), toe_z = rep(0.00, n),
knee_x = rep(0.00, n), knee_y = rep(0.45, n), knee_z = rep(0.00, n),
hip_x = rep(0.00, n), hip_y = rep(0.85, n), hip_z = rep(0.00, n)
)
grf <- data.frame(
fx = rep(50, n), fy = rep(700, n), fz = rep(0, n),
cop_x = rep(0.02, n), cop_y = rep(0, n), cop_z = rep(0, n)
)
out <- inverseDynamics3D(joints, grf, sampling_rate = 100, body_mass = 70)