Skip to content

dynamics

StandardFormEquation(M=dict(), f=None, G=dict()) dataclass

Standard form for one EOM equation.

Σ M[a_j] * a_j + f + Σ G[u_k] * u_k = 0

Attributes

M : dict[str, Expr] Mass/inertia coefficient for each acceleration variable. f : Expr Nonlinear terms (Coriolis, gravity, etc.) — a vector expression. G : dict[str, Expr] Input influence coefficient for each input variable.

SystemVariables(scalars=list(), vectors=list(), matrices=list()) dataclass

Configuration variables that define the degrees of freedom.

scalars: scalar configuration variables (not yet used in EOM pipeline) vectors: vector configuration variables (Vector, S2) matrices: matrix configuration variables (SO3)

compute_eom(lagrangian, inf_work, variables)

Compute equations of motion using the principle of least action.

  1. Take the variation of the Lagrangian: δL
  2. Form the infinitesimal action integral: δS = δL + δW
  3. Apply manifold kinematic substitutions (e.g. δ(ω) for S2)
  4. Simplify
  5. Gather variation vectors and their time derivatives
  6. Integration by parts to move time derivatives off variation vectors
  7. Expand
  8. Extract coefficients of each independent variation vector
Source code in geomech/dynamics/eom.py
def compute_eom(lagrangian, inf_work, variables: SystemVariables):
    """Compute equations of motion using the principle of least action.

    1. Take the variation of the Lagrangian: δL
    2. Form the infinitesimal action integral: δS = δL + δW
    3. Apply manifold kinematic substitutions (e.g. δ(ω) for S2)
    4. Simplify
    5. Gather variation vectors and their time derivatives
    6. Integration by parts to move time derivatives off variation vectors
    7. Expand
    8. Extract coefficients of each independent variation vector
    """
    # variation of the Lagrangian
    dL = lagrangian.delta()

    # infinitesimal action integral
    dS = dL + inf_work

    # apply manifold kinematic substitutions
    dS = apply_manifold_rules(dS, variables)

    dS = full_simplify(dS)

    # gather variation vectors and their time derivatives
    variation_vectors = []
    variation_vector_dots = []

    if variables.scalars:
        raise NotImplementedError(
            "Scalar configuration variables not yet supported in EOM pipeline"
        )

    for vec in variables.vectors:
        x = vec.get_variation_vector()
        variation_vectors.append(x)
        variation_vector_dots.append(x.t_diff())

    for mat in variables.matrices:
        x = mat.get_variation_vector()
        variation_vectors.append(x)
        variation_vector_dots.append(x.t_diff())

    # integration by parts
    dS = integrate_by_parts(dS, variation_vector_dots)

    # expand
    dS = expand(dS)

    # extract equations of motion
    return separate_variations(dS, variation_vectors)

separate_variations(inf_action_integral, variation_vectors)

Extract the equation of motion for each variation vector.

Returns a dict mapping str(variation_vector) → (variation_vector, equation).

Source code in geomech/dynamics/eom.py
def separate_variations(inf_action_integral, variation_vectors):
    """Extract the equation of motion for each variation vector.

    Returns a dict mapping str(variation_vector) → (variation_vector, equation).
    """
    eom = {}
    for vec in variation_vectors:
        dyn_eqn = extract_coeff(inf_action_integral, vec)
        dyn_eqn = full_simplify(dyn_eqn)
        eom[str(vec)] = (vec, dyn_eqn)
    return eom

to_standard_form(eom_dict, variables, inputs=None)

Decompose EOM into standard manipulator form.

Parameters

eom_dict : dict Output of compute_eom(): {str(variation_vec): (variation_vec, eom_expr)}. variables : SystemVariables Configuration variables (used to derive acceleration variables). inputs : list[Expr], optional Input variables (forces, torques). Default: empty.

Returns

dict[str, StandardFormEquation] Keyed by the same variation vector names as eom_dict.

Source code in geomech/dynamics/standard_form.py
def to_standard_form(eom_dict, variables: SystemVariables, inputs=None):
    """Decompose EOM into standard manipulator form.

    Parameters
    ----------
    eom_dict : dict
        Output of ``compute_eom()``:
        ``{str(variation_vec): (variation_vec, eom_expr)}``.
    variables : SystemVariables
        Configuration variables (used to derive acceleration variables).
    inputs : list[Expr], optional
        Input variables (forces, torques). Default: empty.

    Returns
    -------
    dict[str, StandardFormEquation]
        Keyed by the same variation vector names as *eom_dict*.
    """
    if inputs is None:
        inputs = []

    # Derive acceleration variables from config variables
    accel_vars = _get_accel_vars(variables)

    result = {}
    for key, (var_vec, eom_expr) in eom_dict.items():
        sf = _extract_single(eom_expr, accel_vars, inputs)
        result[key] = sf

    return result