dynibo 0.5.2

Tree-structured robot kinematics and dynamics with runtime-size workspace APIs
Documentation
use dynibo::{BaseState, IndexedLoad, Robot};
use nalgebra::{DMatrix, DVector};

pub fn inverse_dynamics_bias(
    robot: &mut Robot,
    _base: &BaseState,
    q: &[f64],
    qd: &[f64],
    loads: &[IndexedLoad],
) -> Vec<f64> {
    let zero = vec![0.0; robot.joint_count()];
    let mut bias = vec![f64::NAN; robot.generalized_count()];
    robot
        .inverse_dynamics(q, qd, &zero, loads, &mut bias)
        .expect("bias inverse dynamics must succeed");
    bias
}

pub fn dense_forward_dynamics(
    robot: &mut Robot,
    base: &BaseState,
    q: &[f64],
    qd: &[f64],
    generalized_forces: &[f64],
    loads: &[IndexedLoad],
) -> Vec<f64> {
    let n = robot.generalized_count();
    assert_eq!(generalized_forces.len(), n);
    let bias = inverse_dynamics_bias(robot, base, q, qd, loads);
    let mut mass = vec![f64::NAN; n * n];
    robot
        .mass_matrix(q, &mut mass)
        .expect("mass matrix must succeed");
    let mass = DMatrix::from_column_slice(n, n, &mass);
    let rhs = DVector::from_iterator(
        n,
        generalized_forces
            .iter()
            .zip(&bias)
            .map(|(force, bias)| force - bias),
    );
    mass.cholesky()
        .expect("well-conditioned test mass matrix must be positive definite")
        .solve(&rhs)
        .as_slice()
        .to_vec()
}

pub fn generalized_force_for_acceleration(
    robot: &mut Robot,
    _base: &BaseState,
    q: &[f64],
    qd: &[f64],
    generalized_acceleration: &[f64],
    loads: &[IndexedLoad],
) -> Vec<f64> {
    assert_eq!(generalized_acceleration.len(), robot.generalized_count());
    let qdd = generalized_acceleration;
    let mut forces = vec![f64::NAN; robot.generalized_count()];
    robot
        .inverse_dynamics(q, qd, qdd, loads, &mut forces)
        .expect("inverse dynamics must produce generalized forces");
    forces
}