示例#1
0
    def convert_array_to_external_forces(all_f_ext):
        if not isinstance(all_f_ext, (list, tuple)):
            raise RuntimeError(
                "f_ext should be a list of (6 x nb_external_forces x nb_shooting) or (6 x nb_shooting) matrix"
            )

        sv_over_all_phases = []
        for f_ext in all_f_ext:
            f_ext = np.array(f_ext)
            if len(f_ext.shape) < 2 or len(f_ext.shape) > 3:
                raise RuntimeError(
                    "f_ext should be a list of (6 x nb_external_forces x nb_shooting) or (6 x nb_shooting) matrix"
                )
            if len(f_ext.shape) == 2:
                f_ext = f_ext[:, :, np.newaxis]

            if f_ext.shape[0] != 6:
                raise RuntimeError(
                    "f_ext should be a list of (6 x nb_external_forces x nb_shooting) or (6 x nb_shooting) matrix"
                )

            sv_over_phase = []
            for node in range(f_ext.shape[2]):
                sv = biorbd.VecBiorbdSpatialVector()
                for idx in range(f_ext.shape[1]):
                    sv.append(biorbd.SpatialVector(MX(f_ext[:, idx, node])))
                sv_over_phase.append(sv)
            sv_over_all_phases.append(sv_over_phase)

        return sv_over_all_phases
示例#2
0
def custom_dynamic(states: MX, controls: MX, parameters: MX,
                   nlp: NonLinearProgram) -> tuple:
    """
    The dynamics of the system using an external force (see custom_dynamics for more explanation)

    Parameters
    ----------
    states: MX
        The current states of the system
    controls: MX
        The current controls of the system
    parameters: MX
        The current parameters of the system
    nlp: NonLinearProgram
        A reference to the phase of the ocp

    Returns
    -------
    The state derivative
    """

    q, qdot, tau = DynamicsFunctions.dispatch_q_qdot_tau_data(
        states, controls, nlp)

    force_vector = MX.zeros(6)
    force_vector[5] = 100 * q[0]**2

    f_ext = biorbd.VecBiorbdSpatialVector()
    f_ext.append(biorbd.SpatialVector(force_vector))
    qddot = nlp.model.ForwardDynamics(q, qdot, tau, f_ext).to_mx()

    return qdot, qddot
def test_forward_dynamics_with_external_forces():
    m = biorbd.Model("../../models/pyomecaman_withActuators.bioMod")

    q = np.array([i * 1.1 for i in range(m.nbQ())])
    qdot = np.array([i * 1.1 for i in range(m.nbQ())])
    tau = np.array([i * 1.1 for i in range(m.nbQ())])

    # With external forces
    if biorbd.currentLinearAlgebraBackend() == 1:
        from casadi import Function, MX
        sv1 = MX((11.1, 22.2, 33.3, 44.4, 55.5, 66.6))
        sv2 = MX((11.1 * 2, 22.2 * 2, 33.3 * 2, 44.4 * 2, 55.5 * 2, 66.6 * 2))
    else:
        sv1 = np.array((11.1, 22.2, 33.3, 44.4, 55.5, 66.6))
        sv2 = np.array(
            (11.1 * 2, 22.2 * 2, 33.3 * 2, 44.4 * 2, 55.5 * 2, 66.6 * 2))

    f_ext = biorbd.VecBiorbdSpatialVector([
        biorbd.SpatialVector(sv1),
        biorbd.SpatialVector(sv2),
    ])

    if biorbd.currentLinearAlgebraBackend() == 1:
        q_sym = MX.sym("q", m.nbQ(), 1)
        qdot_sym = MX.sym("qdot", m.nbQdot(), 1)
        tau_sym = MX.sym("tau", m.nbGeneralizedTorque(), 1)

        ForwardDynamics = Function(
            "ForwardDynamics",
            [q_sym, qdot_sym, tau_sym],
            [m.ForwardDynamics(q_sym, qdot_sym, tau_sym, f_ext).to_mx()],
            ["q_sym", "qdot_sym", "tau_sym"],
            ["qddot"],
        ).expand()

        qddot = ForwardDynamics(q, qdot, tau)
        qddot = np.array(qddot)[:, 0]

    elif biorbd.currentLinearAlgebraBackend() == 0:
        # if Eigen backend is used
        qddot = m.ForwardDynamics(q, qdot, tau, f_ext).to_array()

    qddot_expected = np.array([
        8.8871711208009998,
        -13.647827029817943,
        -33.606145294752132,
        16.922669487341341,
        -21.882821189868423,
        41.15364990805439,
        68.892537246574463,
        -324.59756885799197,
        -447.99217990207387,
        18884.241415786601,
        -331.24622725851572,
        1364.7620674666462,
        3948.4748602722384,
    ])
    np.testing.assert_almost_equal(qddot, qddot_expected)
示例#4
0
def custom_dynamic(states, controls, parameters, nlp):
    q, qdot, tau = DynamicsFunctions.dispatch_q_qdot_tau_data(
        states, controls, nlp)

    force_vector = cas.MX.zeros(6)
    force_vector[5] = 100 * q[0]**2

    f_ext = biorbd.VecBiorbdSpatialVector()
    f_ext.append(biorbd.SpatialVector(force_vector))
    qddot = nlp.model.ForwardDynamics(q, qdot, tau, f_ext).to_mx()

    return qdot, qddot
示例#5
0
def test_forward_dynamics():
    m = biorbd.Model("../../models/pyomecaman_withActuators.bioMod")

    q = np.array([i * 1.1 for i in range(m.nbQ())])
    qdot = np.array([i * 1.1 for i in range(m.nbQ())])
    tau = np.array([i * 1.1 for i in range(m.nbQ())])

    qddot = m.ForwardDynamics(q, qdot, tau).to_array()
    qddot_expected = np.array([
        20.554883896960259,
        -22.317642013324736,
        -77.406439058256126,
        17.382961188212313,
        -63.426361095191858,
        93.816468824985876,
        106.46105024484631,
        95.116641811710167,
        -268.1961283528546,
        2680.3632159799949,
        -183.4582596257801,
        755.89411812405604,
        163.60239754283589,
    ])
    np.testing.assert_almost_equal(qddot, qddot_expected)

    # With external forces
    f_ext = biorbd.VecBiorbdSpatialVector([
        biorbd.SpatialVector(11.1, 22.2, 33.3, 44.4, 55.5, 66.6),
        biorbd.SpatialVector(11.1 * 2, 22.2 * 2, 33.3 * 2, 44.4 * 2, 55.5 * 2,
                             66.6 * 2),
    ])

    qddot = m.ForwardDynamics(q, qdot, tau, f_ext).to_array()
    qddot_expected = np.array([
        8.8871711208009998,
        -13.647827029817943,
        -33.606145294752132,
        16.922669487341341,
        -21.882821189868423,
        41.15364990805439,
        68.892537246574463,
        -324.59756885799197,
        -447.99217990207387,
        18884.241415786601,
        -331.24622725851572,
        1364.7620674666462,
        3948.4748602722384,
    ])
    np.testing.assert_almost_equal(qddot, qddot_expected)
示例#6
0
    def convert_array_to_external_forces(all_f_ext: Union[list, tuple]) -> list:
        """
        Convert external forces np.ndarray lists of external forces to values understood by biorbd

        Parameters
        ----------
        all_f_ext: Union[list, tuple]
            The external forces that acts on the model (the size of the matrix should be
            6 x number of external forces x number of shooting nodes OR 6 x number of shooting nodes)

        Returns
        -------
        The same forces in a biorbd-friendly format
        """

        if not isinstance(all_f_ext, (list, tuple)):
            raise RuntimeError(
                "f_ext should be a list of (6 x n_external_forces x n_shooting) or (6 x n_shooting) matrix"
            )

        sv_over_all_phases = []
        for f_ext in all_f_ext:
            f_ext = np.array(f_ext)
            if len(f_ext.shape) < 2 or len(f_ext.shape) > 3:
                raise RuntimeError(
                    "f_ext should be a list of (6 x n_external_forces x n_shooting) or (6 x n_shooting) matrix"
                )
            if len(f_ext.shape) == 2:
                f_ext = f_ext[:, :, np.newaxis]

            if f_ext.shape[0] != 6:
                raise RuntimeError(
                    "f_ext should be a list of (6 x n_external_forces x n_shooting) or (6 x n_shooting) matrix"
                )

            sv_over_phase = []
            for node in range(f_ext.shape[2]):
                sv = biorbd.VecBiorbdSpatialVector()
                for idx in range(f_ext.shape[1]):
                    sv.append(biorbd.SpatialVector(MX(f_ext[:, idx, node])))
                sv_over_phase.append(sv)
            sv_over_all_phases.append(sv_over_phase)

        return sv_over_all_phases
示例#7
0
    def convert_array_to_external_forces(all_f_ext):
        """
        Converts type of external forces from numpy array to biorbd.SpatialVector
        :param all_f_ext: all external forces (numpy array of size : 6 x number of external forces x number of shooting
        nodes or 6 x number of shooting nodes)
        :return: sv_over_all_phases -> External phases. (biorbd.SpatialVector)
        """
        if not isinstance(all_f_ext, (list, tuple)):
            raise RuntimeError(
                "f_ext should be a list of (6 x nb_external_forces x nb_shooting) or (6 x nb_shooting) matrix"
            )

        sv_over_all_phases = []
        for f_ext in all_f_ext:
            f_ext = np.array(f_ext)
            if len(f_ext.shape) < 2 or len(f_ext.shape) > 3:
                raise RuntimeError(
                    "f_ext should be a list of (6 x nb_external_forces x nb_shooting) or (6 x nb_shooting) matrix"
                )
            if len(f_ext.shape) == 2:
                f_ext = f_ext[:, :, np.newaxis]

            if f_ext.shape[0] != 6:
                raise RuntimeError(
                    "f_ext should be a list of (6 x nb_external_forces x nb_shooting) or (6 x nb_shooting) matrix"
                )

            sv_over_phase = []
            for node in range(f_ext.shape[2]):
                sv = biorbd.VecBiorbdSpatialVector()
                for idx in range(f_ext.shape[1]):
                    sv.append(biorbd.SpatialVector(MX(f_ext[:, idx, node])))
                sv_over_phase.append(sv)
            sv_over_all_phases.append(sv_over_phase)

        return sv_over_all_phases