use phyz_math::DVec;
use phyz_model::{Model, State};
pub fn generalized_forces(model: &Model, state: &State) -> DVec {
let mut qfrc = model.actuator_forces_at(&state.ctrl, &state.q, &state.v);
add_passive_forces(model, state, &mut qfrc);
qfrc
}
pub fn add_passive_forces(model: &Model, state: &State, qfrc: &mut DVec) {
for (j, joint) in model.joints.iter().enumerate() {
let ndof = joint.ndof();
if ndof == 0 {
continue;
}
let q_idx = model.q_offsets[j];
let v_idx = model.v_offsets[j];
for k in 0..ndof {
let q = state.q[q_idx + k];
let qd = state.v[v_idx + k];
qfrc[v_idx + k] += joint.passive_force(k, q, qd);
}
}
}
pub fn armature_diag(model: &Model) -> DVec {
let mut a = DVec::zeros(model.nv);
for (j, joint) in model.joints.iter().enumerate() {
let v_idx = model.v_offsets[j];
for k in 0..joint.ndof() {
a[v_idx + k] = joint.armature;
}
}
a
}