Example #1
0
def exercise2b():
    """ Exercise 2b
    Under isotonic conditions external load is kept constant.
    A constant stimulation is applied and then suddenly the muscle
    is allowed contract. The instantaneous velocity at which the muscle
    contracts is of our interest"""

    # Definition of muscles
    muscle_parameters = MuscleParameters()
    print(muscle_parameters.showParameters())

    mass_parameters = MassParameters()
    print(mass_parameters.showParameters())

    # Create muscle object
    muscle = Muscle.Muscle(muscle_parameters)

    # Point 2d. Different load values.
    biolog.info("Calling for point 2d")
    isoK = isotonic_contraction(muscle)
    lineV = np.arange(-1, 2500, 1)
    zerV = np.zeros(np.size(lineV))
    plt.figure("Plot of Force vs Velocity")
    plt.plot(isoK[0], isoK[1])
    plt.title("Tension vs Normalised Velocity", fontsize=18)
    plt.plot(zerV, lineV, linestyle=':', color='red')
    plt.xlabel('Normalised Velocity [-]')
    plt.ylabel('Total Force of the Muscle [N]')
    plt.legend(['Force/Velocity [N]'])
    plt.minorticks_on()
    plt.grid(which='major', linestyle='-', linewidth='0.5', color='black')
    plt.grid(which='minor', linestyle=':', linewidth='0.5', color='black')
    save_figure('velociplot')
    #    plt.plot(isoK[0], isoK[1], 'o', markersize = 5)

    # Point 2f. Different muscle activation values.
    activations = np.arange(0.5, 1.05, 0.05)
    plt.figure(
        'Muscle Force vs Normalised velocity for varying activation time')
    legend2 = list()
    #print(activations)
    for i, a in enumerate(activations):
        muscle1 = Muscle.Muscle(muscle_parameters)
        #print("Activation = {} [s]".format(a))
        iso = isotonic_contraction(muscle1, activation=a)
        #print("lapin \n {}".format(iso[2]))
        legend2.append("Activation = {} [-]".format(a))
        plt.plot(iso[0], iso[1])  # plot for active force
    plt.xlabel('Normalised Velocity [-]')
    plt.ylabel('Total Force [N]')
    plt.plot(zerV, lineV, linestyle=':', color='red')
    plt.legend(legend2)
    plt.grid()
    plt.minorticks_on()
    plt.grid(which='major', linestyle='-', linewidth='0.5', color='black')
    plt.grid(which='minor', linestyle=':', linewidth='0.5', color='black')
    save_figure('F_vs_Vel_Activations')
Example #2
0
def plot_error(dt_list, err, figure="Average_error", label="Error"):
    """ Plot """
    plt.figure(figure)
    plt.plot(dt_list, err, label=label, linewidth=2.0, marker=".")
    plt.gca().invert_xaxis()
    #plt.xscale('log')
    plt.yscale('log')
    plt.legend(loc="best")
    plt.xlabel("Time step [s]")
    plt.ylabel("Error")
    plt.title(
        "Average error as a function of the timestep size for Runge-Kutta integration compared to the analytical result"
    )
    plt.grid(True)
    from biopack.plot import save_figure
    save_figure(figure)
    return
Example #3
0
def exercise3():
    """ Main function to run for Exercise 3.

    Parameters
    ----------
        None

    Returns
    -------
        None
    """

    # Define and Setup your pendulum model here
    # Check Pendulum.py for more details on Pendulum class
    P_params = PendulumParameters()  # Instantiate pendulum parameters
    P_params.L = .5  # To change the default length of the pendulum
    P_params.mass = 5.  # To change the default mass of the pendulum
    pendulum = Pendulum(P_params)  # Instantiate Pendulum object

    #### CHECK OUT PendulumSystem.py to ADD PERTURBATIONS TO THE MODEL #####

    biolog.info('Pendulum model initialized \n {}'.format(
        pendulum.parameters.showParameters()))

    # Define and Setup your pendulum model here
    # Check MuscleSytem.py for more details on MuscleSytem class
    M1_param = MuscleParameters()  # Instantiate Muscle 1 parameters
    M1_param.f_max = 1500  # To change Muscle 1 max force
    M2_param = MuscleParameters()  # Instantiate Muscle 2 parameters
    M2_param.f_max = 1500  # To change Muscle 2 max force
    M1 = Muscle(M1_param)  # Instantiate Muscle 1 object
    M2 = Muscle(M2_param)  # Instantiate Muscle 2 object
    # Use the MuscleSystem Class to define your muscles in the system
    muscles = MuscleSytem(M1, M2)  # Instantiate Muscle System with two muscles
    biolog.info('Muscle system initialized \n {} \n {}'.format(
        M1.parameters.showParameters(), M2.parameters.showParameters()))
    ###
    ########################################## 3a ########################################
    #
    #    # Define a huge mass, such that the pendulum goes up to pi/2 and up t -pi/2
    #    P_params.mass = 15000.
    #    # Defines 3 different origins and 3 different insertions for each muscle
    #    origins1 = [-0.01, -0.05, -0.10, -0.15, -0.2]
    #    origins2 = map(lambda x: -(x), origins1)
    #    insertions1 = [-0.15, -0.20, -0.25, -0.30]
    #    insertions2 = insertions1[:] # Just for visibility
    #    legendsertion =np.array(['Insertion at -15 cm', 'Insertion at -20 cm', 'Insertion at -25 cm', 'Insertion at -30 cm'])
    #    legleg = np.array(['Insertion at -15 cm', 'Insertion at -15 cm', 'Insertion at -20 cm', 'Insertion at -20 cm', 'Insertion at -25 cm', 'Insertion at -25 cm', 'Insertion at -30 cm', 'Insertion at -30 cm'])
    #    cols = ('blue', 'red', 'olive', 'purple')
    ##    length1 = np.array()
    #
    #    for o1,o2 in zip(origins1, origins2):
    #        fig, (ax1, ax2) = plt.subplots(1,2, sharex = True)
    #        fig.suptitle('Origin of muscles: o1 = {}, o2 = {}'.format(o1,o2), fontsize='26')
    #        for i,j in enumerate(insertions1):
    #            # Define Muscle Attachment points
    #            m1_origin = np.array([o1, 0.0])  # Origin of Muscle 1
    #            m1_insertion = np.array([0.0, j])  # Insertion of Muscle 1
    #
    #            m2_origin = np.array([o2, 0.0])  # Origin of Muscle 2
    #            m2_insertion = np.array([0.0, j])  # Insertion of Muscle 2
    #
    #            # Attach the muscles
    #            muscles.attach(np.array([m1_origin, m1_insertion]),
    #                           np.array([m2_origin, m2_insertion]))
    #
    #            # Create a system with Pendulum and Muscles using the System Class
    #            # Check System.py for more details on System class
    #            sys = System()  # Instantiate a new system
    #            sys.add_pendulum_system(pendulum)  # Add the pendulum model to the system
    #            sys.add_muscle_system(muscles)  # Add the muscle model to the system
    #
    #            ##### Time #####
    #
    #            dt=0.01
    #            t_max = 1.  # Maximum simulation time
    #            time = np.arange(0., t_max, dt)  # Time vector
    #
    #
    #
    #            ##### Model Initial Conditions #####
    #            x0_P = np.array([np.pi/2. - 0.00001,0.])  # Pendulum initial condition
    #
    #            # Muscle Model initial condition
    #            x0_M = np.array([0., M1.l_CE, 0., M2.l_CE])
    #
    #            x0 = np.concatenate((x0_P, x0_M))  # System initial conditions
    #
    #            ##### System Simulation #####
    #            # For more details on System Simulation check SystemSimulation.py
    #            # SystemSimulation is used to initialize the system and integrate
    #            # over time
    #
    #            sim = SystemSimulation(sys)  # Instantiate Simulation object
    #
    #            # Add muscle activations to the simulation
    #            # Here you can define your muscle activation vectors
    #            # that are time dependent
    #
    #            act1=np.ones((len(time),1))*0.05
    #            act2=np.ones((len(time),1))*0.05
    #
    #            activations = np.hstack((act1, act2))
    #
    #            # Method to add the muscle activations to the simulation
    #
    #            sim.add_muscle_activations(activations)
    #
    #            # Simulate the system for given time
    #
    #            sim.initalize_system(x0, time)  # Initialize the system state
    #
    #            # Integrate the system for the above initialized state and time
    #            sim.simulate()
    #
    #            # Obtain the states of the system after integration
    #            # res is np.array [time, states]
    #            # states vector is in the same order as x0
    #            res = sim.results()
    #
    #            # In order to obtain internal paramters of the muscle
    #            # Check SystemSimulation.py results_muscles() method for more information
    #            res_muscles = sim.results_muscles()
    #            length1 = np.array(map(lambda x: np.sqrt(o1**2. + j**2. + 2.*o1*j*np.sin(x)), res[:,1])) # muscle 1 length
    #            length2 = np.array(map(lambda x: np.sqrt(o2**2. + j**2. + 2.*o2*j*np.sin(x)), res[:,1])) # muscle 2 length
    #            # moment arm of muscles calculation
    #            h1lambda = np.array(map(lambda x: np.abs(o1)*np.abs(j)*np.cos(x), res[:,1]))
    #            h2lambda = np.array(map(lambda x: np.abs(o2)*np.abs(j)*np.cos(x), res[:,1]))
    #            h1 = h1lambda/length1
    #            h2 = h2lambda/length2
    #            # Plotting the result for the current origins
    #            ax1.plot(res[:, 1], length1)
    #            ax2.plot(res[:, 1], h1)
    #            if o1 == -0.1:
    #                plt.figure('Muscles\' moment arm for insertions at {} and {}'.format(o1, o2))
    #                if j == -0.15:
    #                    temp = 0.0
    #                    plt.plot(res[:, 1], h1, color=(1.0, temp, 0.0), linestyle = ':')
    #                    plt.plot(res[:, 1], h2, color=(temp, .5, 1.), linestyle = ':')
    #                elif j == -0.2:
    #                    temp = 0.3
    #                    plt.plot(res[:, 1], h1, color=(1.0, temp, 0.0), linestyle = '--')
    #                    plt.plot(res[:, 1], h2, color=(temp, .5, 1.), linestyle = '--')
    #                elif j == -0.25:
    #                    temp = 0.7
    #                    plt.plot(res[:, 1], h1, color=(1.0, temp, 0.0), linestyle = '-.')
    #                    plt.plot(res[:, 1], h2, color=(temp, .5, 1.), linestyle = '-.')
    #                else:
    #                    temp = 1.0
    #                    plt.plot(res[:, 1], h1, color=(1.0, temp, 0.0))
    #                    plt.plot(res[:, 1], h2, color=(temp, .5, 1.))
    #                plt.legend(legleg)
    #                plt.xlabel('Pendulum position [rad]', fontsize = '18')
    #                plt.ylabel('Muscle moment arm [m]', fontsize = '18')
    #                plt.title('Muscles\' moment arm for insertions at {} and {}.\nRedish = muscle 1 (left), Blueish = muscle 2 (right)'.format(o1, o2), fontsize='26')
    #                plt.grid('ON')
    #
    #        ax1.legend(legendsertion)
    #        ax2.legend(legendsertion)
    #        ax1.set_xlabel('Position [rad]', fontsize='18')
    #        ax2.set_xlabel('Position [rad]', fontsize='18')
    #        ax1.set_ylabel('Muscle length [m]', fontsize='18') # Here we computed length 1 but muscle 2 has the same behaviour for identical params
    #        ax2.set_ylabel('Muscle moment arm [m]', fontsize='18')
    #        ax1.set_title('Muscle-tendon unit length in terms of pendulum position', fontsize='20')
    #        ax2.set_title('Muscle\'s moment arm', fontsize='20')
    #        ax1.grid()
    #        ax2.grid()
    #
    ######################################## End OF 3a ########################################
    ##
    ########################################## 3b ########################################
    #
    #    # Define a huge mass, such that the pendulum goes up to pi/2 and up t -pi/2
    #    P_params.mass = 1500.
    #    # Defines 3 different origins and 3 different insertions for each muscle
    #    origins1 = [-0.01, -0.05, -0.10, -0.15, -0.2]
    #    origins2 = map(lambda x: -(x), origins1)
    #    insertions1 = [-0.15, -0.20, -0.25, -0.30]
    #    insertions2 = insertions1[:] # Just for visibility
    #    legendsertion =np.array(['Insertion at -15 cm', 'Insertion at -20 cm', 'Insertion at -25 cm', 'Insertion at -30 cm'])
    #    legleg = np.array(['Insertion at -15 cm', 'Insertion at -15 cm', 'Insertion at -20 cm', 'Insertion at -20 cm', 'Insertion at -25 cm', 'Insertion at -25 cm', 'Insertion at -30 cm', 'Insertion at -30 cm'])
    #    cols = ('blue', 'red', 'olive', 'purple')
    ##    length1 = np.array()
    #
    #    for o1,o2 in zip(origins1, origins2):
    #        fig, (ax1, ax2) = plt.subplots(1,2, sharex = True)
    #        fig.suptitle('Origin of muscles - passive: o1 = {}, o2 = {}'.format(o1,o2), fontsize='26')
    #        for i,j in enumerate(insertions1):
    #            # Define Muscle Attachment points
    #            m1_origin = np.array([o1, 0.0])  # Origin of Muscle 1
    #            m1_insertion = np.array([0.0, j])  # Insertion of Muscle 1
    #
    #            m2_origin = np.array([o2, 0.0])  # Origin of Muscle 2
    #            m2_insertion = np.array([0.0, j])  # Insertion of Muscle 2
    #
    #            # Attach the muscles
    #            muscles.attach(np.array([m1_origin, m1_insertion]),
    #                           np.array([m2_origin, m2_insertion]))
    #
    #            # Create a system with Pendulum and Muscles using the System Class
    #            # Check System.py for more details on System class
    #            sys = System()  # Instantiate a new system
    #            sys.add_pendulum_system(pendulum)  # Add the pendulum model to the system
    #            sys.add_muscle_system(muscles)  # Add the muscle model to the system
    #
    #            ##### Time #####
    #
    #            dt=0.01
    #            t_max = 1.  # Maximum simulation time
    #            time = np.arange(0., t_max, dt)  # Time vector
    #
    #
    #
    #            ##### Model Initial Conditions #####
    #            x0_P = np.array([np.pi/2. - 0.00001,0.])  # Pendulum initial condition
    #
    #            # Muscle Model initial condition
    #            x0_M = np.array([0., M1.l_CE, 0., M2.l_CE])
    #
    #            x0 = np.concatenate((x0_P, x0_M))  # System initial conditions
    #
    #            ##### System Simulation #####
    #            # For more details on System Simulation check SystemSimulation.py
    #            # SystemSimulation is used to initialize the system and integrate
    #            # over time
    #
    #            sim = SystemSimulation(sys)  # Instantiate Simulation object
    #
    #            # Add muscle activations to the simulation
    #            # Here you can define your muscle activation vectors
    #            # that are time dependent
    #
    #            act1=np.ones((len(time),1))*0.00 # Passive muscles, unactivated.
    #            act2=np.ones((len(time),1))*0.00
    #
    #            activations = np.hstack((act1, act2))
    #
    #            # Method to add the muscle activations to the simulation
    #
    #            sim.add_muscle_activations(activations)
    #
    #            # Simulate the system for given time
    #
    #            sim.initalize_system(x0, time)  # Initialize the system state
    #
    #            # Integrate the system for the above initialized state and time
    #            sim.simulate()
    #
    #            # Obtain the states of the system after integration
    #            # res is np.array [time, states]
    #            # states vector is in the same order as x0
    #            res = sim.results()
    #
    #            # In order to obtain internal paramters of the muscle
    #            # Check SystemSimulation.py results_muscles() method for more information
    #            res_muscles = sim.results_muscles()
    #            length1 = np.array(map(lambda x: np.sqrt(o1**2. + j**2. + 2.*o1*j*np.sin(x)), res[:,1])) # muscle 1 length
    #            length2 = np.array(map(lambda x: np.sqrt(o2**2. + j**2. + 2.*o2*j*np.sin(x)), res[:,1])) # muscle 2 length
    #            # moment arm of muscles calculation
    #            h1lambda = np.array(map(lambda x: np.abs(o1)*np.abs(j)*np.cos(x), res[:,1]))
    #            h2lambda = np.array(map(lambda x: np.abs(o2)*np.abs(j)*np.cos(x), res[:,1]))
    #            h1 = h1lambda/length1
    #            h2 = h2lambda/length2
    #            # Plotting the result for the current origins
    #            ax1.plot(res[:, 1], length1)
    #            ax2.plot(res[:, 1], h1)
    #            if o1 == -0.1:
    #                plt.figure('Muscles\' moment arm for insertions at {} and {} - passive'.format(o1, o2))
    #                if j == -0.15:
    #                    temp = 0.0
    #                    plt.plot(res[:, 1], h1, color=(1.0, temp, 0.0), linestyle = ':')
    #                    plt.plot(res[:, 1], h2, color=(temp, .5, 1.), linestyle = ':')
    #                elif j == -0.2:
    #                    temp = 0.3
    #                    plt.plot(res[:, 1], h1, color=(1.0, temp, 0.0), linestyle = '--')
    #                    plt.plot(res[:, 1], h2, color=(temp, .5, 1.), linestyle = '--')
    #                elif j == -0.25:
    #                    temp = 0.7
    #                    plt.plot(res[:, 1], h1, color=(1.0, temp, 0.0), linestyle = '-.')
    #                    plt.plot(res[:, 1], h2, color=(temp, .5, 1.), linestyle = '-.')
    #                else:
    #                    temp = 1.0
    #                    plt.plot(res[:, 1], h1, color=(1.0, temp, 0.0))
    #                    plt.plot(res[:, 1], h2, color=(temp, .5, 1.))
    #                plt.legend(legleg)
    #                plt.xlabel('Pendulum position [rad]', fontsize = '18')
    #                plt.ylabel('Muscle moment arm [m]', fontsize = '18')
    #                plt.title('Muscles\' moment arm for insertions at {} and {} - passive.\nRedish = muscle 1 (left), Blueish = muscle 2 (right)'.format(o1, o2), fontsize='26')
    #                plt.grid('ON')
    #
    #        ax1.legend(legendsertion)
    #        ax2.legend(legendsertion)
    #        ax1.set_xlabel('Position [rad]', fontsize='18')
    #        ax2.set_xlabel('Position [rad]', fontsize='18')
    #        ax1.set_ylabel('Muscle length [m]', fontsize='18') # Here we computed length 1 but muscle 2 has the same behaviour for identical params
    #        ax2.set_ylabel('Muscle moment arm [m]', fontsize='18')
    #        ax1.set_title('Muscle-tendon unit length in terms of pendulum position', fontsize='20')
    #        ax2.set_title('Muscle\'s moment arm', fontsize='20')
    #        ax1.grid()
    #        ax2.grid()
    #
    ######################################## End OF 3b ########################################
    ######################################## Part 3c,d,e,f ##########################################

    LC = True  # Limit Cycle ON => LC True, Limit Cyle OFF => LC False

    if LC == True:
        P_params.mass = 10.
    else:
        P_params.mass = 100.

    # For point 3f, we changed max forces up here (line 55 and 57)

    # Define Muscle Attachment points
    m1_origin = np.array([-0.17, 0.0])  # Origin of Muscle 1
    m1_insertion = np.array([0.0, -0.17])  # Insertion of Muscle 1

    m2_origin = np.array([0.17, 0.0])  # Origin of Muscle 2
    m2_insertion = np.array([0.0, -0.17])  # Insertion of Muscle 2

    # Attach the muscles
    muscles.attach(np.array([m1_origin, m1_insertion]),
                   np.array([m2_origin, m2_insertion]))

    # Create a system with Pendulum and Muscles using the System Class
    # Check System.py for more details on System class
    sys = System()  # Instantiate a new system
    sys.add_pendulum_system(pendulum)  # Add the pendulum model to the system
    sys.add_muscle_system(muscles)  # Add the muscle model to the system

    ##### Time #####

    dt = 0.01
    t_max = 5.  # Maximum simulation time
    time = np.arange(0., t_max, dt)  # Time vector

    ##### Model Initial Conditions #####
    x0_P = np.array([2 * np.pi / 6., 0.])  # Pendulum initial condition

    # Muscle Model initial condition
    x0_M = np.array([0., M1.l_CE, 0., M2.l_CE])

    x0 = np.concatenate((x0_P, x0_M))  # System initial conditions

    ##### System Simulation #####
    # For more details on System Simulation check SystemSimulation.py
    # SystemSimulation is used to initialize the system and integrate
    # over time

    sim = SystemSimulation(sys)  # Instantiate Simulation object

    # Add muscle activations to the simulation
    # Here you can define your muscle activation vectors
    # that are time dependent

    act1 = np.arange(0., t_max, dt)
    act2 = np.arange(0., t_max, dt)

    if LC == True:
        act1 = (np.sin(2. * np.pi / t_max * 5. * act1) +
                1.) * .5  # acts = time
        act2 = (
            -np.sin(2. * np.pi / t_max * 5. * act2) + 1.
        ) * .5  # by increasing frequency, we don't let the time to gravity to make its office and contribute to the system's equilibrium, so the amplitude of the pendulum diminues.
        act1 = act1.reshape(len(act1), 1)
        act2 = act2.reshape(len(act2), 1)
    else:
        act1 = np.ones((len(time), 1)) * 0.25
        act2 = np.ones((len(time), 1)) * 0.25

    activations = np.hstack((act1, act2))
    # Method to add the muscle activations to the simulation

    sim.add_muscle_activations(activations)

    # Simulate the system for given time

    sim.initalize_system(x0, time)  # Initialize the system state

    # Integrate the system for the above initialized state and time
    sim.simulate()

    # Obtain the states of the system after integration
    # res is np.array [time, states]
    # states vector is in the same order as x0
    res = sim.results()

    # In order to obtain internal paramters of the muscle
    # Check SystemSimulation.py results_muscles() method for more information
    res_muscles = sim.results_muscles()

    # Plotting the results
    plt.figure('Pendulum')
    #    plt.title('Pendulum Phase')
    plt.title('Limit cycle behaviour for a max force of {} N'.format(M1.F_max),
              fontsize='22')
    #    plt.plot(res[:, 1], res[:, 2])
    plt.plot(time, res[:, 1])
    #    plt.xlabel('Position [rad]')
    #    plt.ylabel('Velocity [rad.s]')
    plt.xlabel('Time [s]')
    plt.ylabel('Pendulum position [rad]')
    plt.grid()

    # Plotting activation
    legact = ("Muscle 1 - left", "Muscle 2 - right")
    plt.figure('Activations')
    #    plt.title('Pendulum Phase')
    plt.title('Muscle activation patterns', fontsize='22')
    #    plt.plot(res[:, 1], res[:, 2])
    plt.plot(time, act1, color='red')
    plt.plot(time, act2, color='green')
    #    plt.xlabel('Position [rad]')
    #    plt.ylabel('Velocity [rad.s]')
    plt.xlabel('Time [s]')
    plt.ylabel('Activation [-]')
    plt.legend(legact)
    plt.grid()

    if DEFAULT["save_figures"] is False:
        plt.show()
    else:
        figures = plt.get_figlabels()
        biolog.debug("Saving figures:\n{}".format(figures))
        for fig in figures:
            plt.figure(fig)
            save_figure(fig)
            plt.close(fig)

    # To animate the model, use the SystemAnimation class
    # Pass the res(states) and systems you wish to animate
    simulation = SystemAnimation(res, pendulum, muscles)
    # To start the animation
    simulation.animate()
Example #4
0
def exercise4():
    """ Main function to run for Exercise 3.

    Parameters
    ----------
        None

    Returns
    -------
        None
    """
    # Define and Setup your pendulum model here
    # Check Pendulum.py for more details on Pendulum class
    P_params = PendulumParameters()  # Instantiate pendulum parameters
    P_params.L = 0.5  # To change the default length of the pendulum
    P_params.mass = 1.  # To change the default mass of the pendulum
    pendulum = Pendulum(P_params)  # Instantiate Pendulum object

    #### CHECK OUT Pendulum.py to ADD PERTURBATIONS TO THE MODEL #####

    biolog.info('Pendulum model initialized \n {}'.format(
        pendulum.parameters.showParameters()))

    # Define and Setup your pendulum model here
    # Check MuscleSytem.py for more details on MuscleSytem class
    M1_param = MuscleParameters()  # Instantiate Muscle 1 parameters
    M1_param.f_max = 1500  # To change Muscle 1 max force
    M2_param = MuscleParameters()  # Instantiate Muscle 2 parameters
    M2_param.f_max = 1500  # To change Muscle 2 max force
    M1 = Muscle(M1_param)  # Instantiate Muscle 1 object
    M2 = Muscle(M2_param)  # Instantiate Muscle 2 object
    # Use the MuscleSystem Class to define your muscles in the system
    muscles = MuscleSytem(M1, M2)  # Instantiate Muscle System with two muscles
    biolog.info('Muscle system initialized \n {} \n {}'.format(
        M1.parameters.showParameters(),
        M2.parameters.showParameters()))

    # Define Muscle Attachment points
    m1_origin = np.array([-0.10, 0.0])  # Origin of Muscle 1
    m1_insertion = np.array([0.0, -0.17])  # Insertion of Muscle 1

    m2_origin = np.array([0.17, 0.0])  # Origin of Muscle 2
    m2_insertion = np.array([0.0, -0.10])  # Insertion of Muscle 2

    # Attach the muscles
    muscles.attach(np.array([m1_origin, m1_insertion]),
                   np.array([m2_origin, m2_insertion]))

    ##### Neural Network #####
    
    # The network consists of four neurons
    N_params = NetworkParameters()  # Instantiate default network parameters
    N_params.D = 1.  # To change a network parameter
    # Similarly to change w -> N_params.w = (4x4) array
    N_params.w=[[.0,-5.,-5.0,0.],
              [-5.,0.,.0,-5.0],
              [3.0,-1.0,.0,.0],
              [-1.0,3.,.0,.0]]
    
    N_params.b=[3.0,3.0,-3.0,-3.]
    N_params.tau=[.02,.02,.1,.1]
    biolog.info(N_params.showParameters())

    # Create a new neural network with above parameters
    neural_network = NeuralSystem(N_params)

    # Create system of Pendulum, Muscles and neural network using SystemClass
    # Check System.py for more details on System class
    sys = System()  # Instantiate a new system
    sys.add_pendulum_system(pendulum)  # Add the pendulum model to the system
    sys.add_muscle_system(muscles)  # Add the muscle model to the system
    # Add the neural network to the system
    sys.add_neural_system(neural_network)

    ##### Time #####
    t_max = 20.  # Maximum simulation time
    time = np.arange(0., t_max, 0.001)  # Time vector

    ##### Model Initial Conditions #####
    x0_P = np.array([0., 0.])  # Pendulum initial condition

    # Muscle Model initial condition
    x0_M = np.array([0., M1.l_CE, 0., M2.l_CE])

    x0_N = np.array([-0.5, 1, 0.5, 1])  # Neural Network Initial Conditions

    x0 = np.concatenate((x0_P, x0_M, x0_N))  # System initial conditions

    ##### System Simulation #####
    # For more details on System Simulation check SystemSimulation.py
    # SystemSimulation is used to initialize the system and integrate
    # over time

    sim = SystemSimulation(sys)  # Instantiate Simulation object

    # Add external inputs to neural network
    heaviside=np.heaviside(time - np.mean(time),0.5)
    h4=np.zeros((len(time),4))
    
    h4[:,0]=heaviside
    h4[:,1]=heaviside
    h4[:,2]=heaviside
    h4[:,3]=heaviside
    sim.add_external_inputs_to_network(h4) # Activates the external drive to its max (1)
    # sim.add_external_inputs_to_network(ext_in)

    sim.initalize_system(x0, time)  # Initialize the system state

    # Integrate the system for the above initialized state and time
    sim.simulate()

    # Obtain the states of the system after integration
    # res is np.array [time, states]
    # states vector is in the same order as x0
    res = sim.results()

    # In order to obtain internal paramters of the muscle
    # Check SystemSimulation.py results_muscles() method for more information
    res_muscles = sim.results_muscles()

    # Plotting the results
    plt.figure('Pendulum')
    plt.title('Pendulum Phase',fontsize = '18')
    plt.plot(res[:, 1], res[:, 2])
    plt.xlabel('Position [rad]',fontsize = '16')
    plt.ylabel('Velocity [rad/s]', fontsize = '16')
    plt.grid()

    if DEFAULT["save_figures"] is False:
        plt.show()
    else:
        figures = plt.get_figlabels()
        biolog.debug("Saving figures:\n{}".format(figures))
        for fig in figures:
            plt.figure(fig)
            save_figure(fig)
            plt.close(fig)

    # To animate the model, use the SystemAnimation class
    # Pass the res(states) and systems you wish to animate
    simulation = SystemAnimation(res, pendulum, muscles, neural_network)
    # To start the animation
    simulation.animate()
    
        # Plotting the results
    plt.figure('Time & Phase')
    plt.subplot(2,1,1)
    plt.plot(res[:,0],res[:,1])
#    plt.xlabel('Time [s]')
    plt.grid()
    plt.ylabel('Pos. [rad]',fontsize = '16')
    plt.title('Position',fontsize = '18')
    plt.subplot(2,1,2)
    plt.title('Velocity',fontsize = '18')
    plt.plot(res[:,0],res[:,2])
    plt.xlabel('Time [s]',fontsize = '16')
    plt.ylabel('Vel [rad/s]',fontsize = '16')
    plt.grid()
    plt.show()
Example #5
0
def exercise2a():
    """ Exercise 2a
    The goal of this exercise is to understand the relationship
    between muscle length and tension.
    Here you will re-create the isometric muscle contraction experiment.
    To do so, you will have to keep the muscle at a constant length and
    observe the force while stimulating the muscle at a constant activation."""

    font1 = {'family': 'normal', 'weight': 'bold', 'size': 18}
    font2 = {'family': 'normal', 'weight': 'normal', 'size': 12}

    # Definition of muscles
    parameters = MuscleParameters()
    biolog.warning("Loading default muscle parameters")
    biolog.info(parameters.showParameters())

    # Create muscle object
    muscle = Muscle.Muscle(parameters)

    # Isometric contraction, varying the activation between [0-1]
    isoM = isometric_contraction(muscle)
    legend1 = ("Passive Force", "Active Force", "Total Force")
    plt.figure('Forces vs Length')
    plt.title("Force-Length relationship")
    plt.plot(isoM[0], isoM[1])
    plt.plot(isoM[0], isoM[2])
    plt.plot(isoM[0], isoM[3])
    plt.xlabel('Total length of the contractile element [m]')
    plt.ylabel('Force [N]')
    plt.legend(legend1)
    plt.grid()
    save_figure('F_vs_length')

    # Stabilisation has been verified for integrating the muscle for 0.2s. However, to be sure, we integrated it for 0.25s
    #    plt.figure("Stab??")
    #    plt.plot(isoM[4],isoM[5])

    # Effect of varying l_opt (fiber length) NOT SURE)
    muscleS = Muscle.Muscle(parameters)  # 'short' muscle
    muscleS.l_opt = 0.05  # short fiber length
    muscleL = Muscle.Muscle(parameters)  # 'long' muscle
    muscleL.l_opt = 0.25  # long fiber length
    muscleXL = Muscle.Muscle(parameters)  # 'extra long' muscle
    muscleXL.l_opt = 0.50  # extra long fiber length
    isoS = isometric_contraction(muscleS,
                                 stretch=np.arange(-0.25, 0.25, 0.001),
                                 activation=0.25)
    isoL = isometric_contraction(muscleL,
                                 stretch=np.arange(-0.25, 0.25, 0.001),
                                 activation=0.25)
    isoXL = isometric_contraction(muscleXL,
                                  stretch=np.arange(-0.25, 0.25, 0.001),
                                  activation=0.25)
    legendS = ("Short fibers: {} [m], \n max_total_length: {} [m]".format(
        muscleS.l_opt, np.max(isoS[0])),
               "Long fibers: {} [m], \n max_total_length: {} [m]".format(
                   muscleL.l_opt, np.max(isoL[0])),
               "Extra Long fibers: {} [m], \n max_total_length: {} [m]".format(
                   muscleXL.l_opt, np.max(isoXL[0])))
    plt.figure(
        'Short, Long and Extra Long muscle fibers (l_opt) active force vs length'
    )
    plt.title(
        "Stretching of -25% to +25% and activation of 25% for each muscle type"
    )
    plt.plot((isoS[0]) / (np.max(isoS[0])) * 100,
             isoS[2])  # we plot the percentage of total length
    plt.plot((isoL[0]) / (np.max(isoL[0])) * 100, isoL[2])
    plt.plot((isoXL[0]) / (np.max(isoXL[0])) * 100, isoXL[2])
    plt.xlabel(
        'Percentage of maximal total length (l_CE + stretching) of the contractile element [m]'
    )
    plt.ylabel('Active Force [N]')
    plt.legend(legendS)
    plt.grid()
    plt.minorticks_on()
    plt.grid(which='major', linestyle='-', linewidth='0.5', color='black')
    plt.grid(which='minor', linestyle=':', linewidth='0.5', color='black')
    save_figure('short_vs_long_vs_xtraLong')

    legendSx = ("Short fibers: {} [m], \n max_total_length: {} [m]".format(
        muscleS.l_opt, np.max(isoS[0])),
                "Long fibers: {} [m], \n max_total_length: {} [m]".format(
                    muscleL.l_opt, np.max(isoL[0])))
    plt.figure('Short and Long muscle fibers (l_opt) active force vs length')
    plt.plot(isoS[0], isoS[2])
    plt.plot(isoL[0], isoL[2])
    plt.xlabel('Length (l_CE + stretching) of the contractile element [m]')
    plt.ylabel('Active Force [N]')
    plt.legend(legendSx)
    plt.grid()
    plt.minorticks_on()
    plt.grid(which='major', linestyle='-', linewidth='0.5', color='black')
    plt.grid(which='minor', linestyle=':', linewidth='0.5', color='black')
    save_figure('short_vs_Long')

    # Effect of varying activation (stimulation)
    activations = np.arange(0.0, 1.05, 0.05)
    max_F_Diff = np.zeros(
        np.size(activations)
    )  # vectors to assess the evolution of the difference of the maximas of passive and active force
    ratio = np.zeros(
        np.size(activations)
    )  # to implement the total_force/total_length ratio for every activation value
    plt.figure('Active force vs Length with varying activation time')
    legend2 = list()
    #print(activations)
    for i, a in enumerate(activations):
        muscle1 = Muscle.Muscle(parameters)
        #print("Activation = {} [s]".format(a))
        iso = isometric_contraction(muscle1, activation=a)
        #print("lapin \n {}".format(iso[2]))
        legend2.append("Activation = {} [-]".format(a))
        plt.plot(iso[0], iso[2])  # plot for active force
        #        plt.plot(iso[0],iso[3]) # plot for total force
        max_F_Diff[i] = np.abs(np.max(iso[1]) - np.max(iso[2]))
        ratio[i] = ((np.mean(iso[3])) / (np.mean(iso[0]))) / 1000
    plt.xlabel('Total length of the contractile element [m]')
    plt.ylabel('Force [N]')
    plt.legend(legend2)
    plt.grid()
    save_figure('F_vs_length')

    # Force difference figure
    plt.figure(
        'Difference between the max of the passive and the active force')
    plt.plot(activations,
             max_F_Diff,
             color='black',
             marker='v',
             linestyle='dashed',
             linewidth=1,
             markersize=5)
    plt.xlabel('Activation value [s]')
    plt.ylabel('Force Difference [N]')
    plt.legend(['$\Delta$'])
    plt.minorticks_on()
    plt.grid(which='major', linestyle='-', linewidth='0.5', color='red')
    plt.grid(which='minor', linestyle=':', linewidth='0.5', color='black')
    save_figure('delta_plot')

    # Force/length ratio
    plt.figure(
        'Ratio between the total force (active + passive) and the total length of the contractile element'
    )
    plt.plot(activations,
             ratio,
             color='black',
             marker='v',
             linestyle='dashed',
             linewidth=1,
             markersize=5)
    plt.xlabel('Activation value [-]')
    plt.ylabel('(Total_force/total_length)/1000  [N]/[m]')
    plt.legend(['$Ratio$'])
    plt.minorticks_on()
    plt.grid(which='major', linestyle='-', linewidth='0.5', color='red')
    plt.grid(which='minor', linestyle=':', linewidth='0.5', color='black')
    save_figure('ratio_plot')

    biolog.info("Isometric muscle contraction implemented")
    """ Example for plotting graphs using matplotlib. """