def run_N_sim_MAV(**kwargs):
    NumberOfTrials = kwargs.get("NumberOfTrials", 10)

    TotalX = np.zeros((NumberOfTrials, 8, N))
    TotalU = np.zeros((NumberOfTrials, 2, N))
    TerminalWidth = get_terminal_width()

    print("\n")
    for j in range(NumberOfTrials):
        TrialTitle = ("          Trial " + str(j + 1) + "/" +
                      str(NumberOfTrials) + "          \n")
        print(" " * int(TerminalWidth / 2 - len(TrialTitle) / 2) +
              colored(TrialTitle, 'white', attrs=["underline", "bold"]))
        TotalX[j], TotalU[j] = run_sim_MAV(**kwargs)

    i = 0
    NumberOfSuccessfulTrials = NumberOfTrials
    while i < NumberOfSuccessfulTrials:
        if (TotalX[i] == np.zeros((8, np.shape(TotalX)[2]))).all():
            TotalX = np.delete(TotalX, i, 0)
            TotalU = np.delete(TotalU, i, 0)
            NumberOfSuccessfulTrials -= 1
            if NumberOfSuccessfulTrials == 0:
                raise ValueError("No Successful Trials!")
        else:
            i += 1

    print("Number of Desired Runs: " + str(NumberOfTrials) + "\n" +
          "Number of Successful Runs: " + str(NumberOfSuccessfulTrials) + "\n")
    return (TotalX, TotalU)
예제 #2
0
def run_sim_rand_TT(N, **kwargs):
    """
    Runs one simulation for MINIMUM ACTIVATION TRANSITION control.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    **kwargs
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    1) Bounds - must be a (2,2) list with each row in ascending order. Default is given by Tension_Bounds.

    2) InitialAngularAcceleration - must be a float or an int. Default is 0 (starting from rest).

    3) thresh - must be an int. Default is 25.

    """
    thresh = kwargs.get("thresh", 25)
    assert type(
        thresh
    ) == int, "thresh should be an int as it is the number of attempts the program should run before stopping."

    AnotherIteration = True
    AttemptNumber = 1

    while AnotherIteration == True:
        X = np.zeros((2, N))
        X_o, InitialTensions = find_initial_values_TT(**kwargs)
        X[:, 0] = X_o
        U = np.zeros((2, N))
        U[:, 0] = InitialTensions.T

        AddNoise = False
        if AddNoise == True:
            np.random.seed(seed=None)
            NoiseArray = np.random.normal(loc=0.0, scale=0.2, size=(2, N))
        else:
            NoiseArray = np.zeros((2, N))

        try:
            cprint("Attempt #" + str(int(AttemptNumber)) + ":\n", 'green')
            statusbar = dsb(0, N - 1, title=run_sim_rand_TT.__name__)
            for i in range(N - 1):
                U[:, i + 1] = return_U_random_tensions(i,
                                                       Time,
                                                       X[:, i],
                                                       U[:, i],
                                                       Noise=NoiseArray[:, i])
                X[:,i+1] = X[:,i] + dt*np.array([ dX1_dt(X[:,i]),\
                         dX2_dt(X[:,i],U=U[:,i+1])])
                statusbar.update(i)
            AnotherIteration = False
            return (X, U)
        except:
            print('\n')
            print(" "*(get_terminal_width()\
               - len("...Attempt #" + str(int(AttemptNumber)) + " Failed. "))\
               + colored("...Attempt #" + str(int(AttemptNumber)) + " Failed. \n",'red'))
            AttemptNumber += 1
            if AttemptNumber > thresh:
                AnotherIteration = False
                return (np.zeros((2, N)), np.zeros((2, N)))
def run_N_sim_IB_sinus_act(**kwargs):
    """
    Runs one simulation for sinusoidal u1 control.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    **kwargs (most are passed to run_sim_IB_sinus_act())
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    1) Bounds - must be a (2,2) list with each row in ascending order. Default is given by Tension_Bounds.

    2) InitialAngularAcceleration - must be a float or an int. Default is 0 (starting from rest).

    3) thresh - must be an int. Default is 25.

    4) FixedInitialTension - will be passed to find_viable_initial_values and will fix the value of initial tension. Must be a (2,) numpy.ndarray. Run find_initial_tension outside of the loop for a given seed and then feed it through the pipeline.

    5) Amps - list of length 2 that has the amplitudes of sinusoidal activation trajectories.

    6) Freq - scalar value given in Hz.

    7) PhaseOffset - scalar value in [0,2*np.pi).

    8) InitialTensionAcceleration - will be passed to find_viable_initial_values(**kwargs). Must be a numpy array of shape (2,)

    9) NumberOfTrials - should be an int.

    10) FixedInitialMuscleLengths - must be a list of length 2 or None (Default). If is None, then program will assign this value randomly. Used for trials where we wish to hold muscle length constant for different tension levels. Will be passed to run_sim_IB_sinus_act(...)
    """
    NumberOfTrials = kwargs.get("NumberOfTrials", 10)
    assert type(
        NumberOfTrials
    ) == int and NumberOfTrials > 0, "NumberOfTrials must be an positive int."

    TotalX = np.zeros((NumberOfTrials, 8, N))
    TotalU = np.zeros((NumberOfTrials, 2, N))
    TerminalWidth = get_terminal_width()

    print("\n")
    for j in range(NumberOfTrials):
        TrialTitle = ("          Trial " + str(j + 1) + "/" +
                      str(NumberOfTrials) + "          \n")
        print(" " * int(TerminalWidth / 2 - len(TrialTitle) / 2) +
              colored(TrialTitle, 'white', attrs=["underline", "bold"]))
        TotalX[j], TotalU[j] = run_sim_IB_sinus_act(**kwargs)
    i = 0
    NumberOfSuccessfulTrials = NumberOfTrials
    while i < NumberOfSuccessfulTrials:
        if (TotalX[i] == np.zeros((8, np.shape(TotalX)[2]))).all():
            TotalX = np.delete(TotalX, i, 0)
            TotalU = np.delete(TotalU, i, 0)
            NumberOfSuccessfulTrials -= 1
            if NumberOfSuccessfulTrials == 0:
                raise ValueError("No Successful Trials!")
        else:
            i += 1

    print("Number of Desired Runs: " + str(NumberOfTrials) + "\n" +
          "Number of Successful Runs: " + str(NumberOfSuccessfulTrials) + "\n")
    return (TotalX, TotalU)
예제 #4
0
def run_sim_FF_sinus_act(**kwargs):
    """
    Runs one simulation for FEEDFORWARD SINUSOIDAL INPUT control.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    **kwargs
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    1) Bounds - must be a (2,2) list with each row in ascending order. Default is given by Tension_Bounds.

    2) InitialAngularAcceleration - must be a float or an int. Default is 0 (starting from rest).

    3) thresh - must be an int. Default is 25.

    4) FixedInitialTension - will be passed to find_viable_initial_values and will fix the value of initial tension. Must be a (2,) numpy.ndarray. Run find_initial_tension outside of the loop for a given seed and then feed it through the pipeline.

    5) Amps - list of length 2 that has the amplitudes of sinusoidal activation trajectories.

    6) Freq - scalar value given in Hz.

    7) PhaseOffset - scalar value in [0,360).

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    **kwargs (Passed to find_viable_initial_values())
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    8) InitialAngularAcceleration - must be either a numpy.float64, float, or int. Default is set to 0 to simulate starting from rest. Choice of reference trajectory *should* not matter as it is either 0 or d2r(0) (either by convention or by choice).

    9) InitialAngularSnap - must be either a numpy.float64, float, or int. Default is set to 0 to simulate starting from rest. Choice of reference trajectory *should* not matter as it is either 0 or d4r(0) (either by convention or by choice).

    """
    thresh = kwargs.get("thresh", 25)
    assert type(
        thresh
    ) == int, "thresh should be an int as it is the number of attempts the program should run before stopping."

    Bounds = kwargs.get("Bounds", ActivationBounds)
    assert type(Bounds) == list and np.shape(Bounds) == (
        2, 2), "Bounds should be a list of shape (2,2)."

    Amps = kwargs.get("Amps", [0.1, 0.1])
    if Amps != "Scaled":
        assert type(Amps) == list and len(
            Amps
        ) == 2, "Amps should be a list of length 2 with values that are within activation bounds."

    Freq = kwargs.get("Freq", 1)
    assert type(Freq) in [int, float], "Freq should be an int or a float."

    PhaseOffset = kwargs.get("PhaseOffset", 90)
    assert (type(PhaseOffset) in [
        int, float
    ]) and (0 <= PhaseOffset <
            360), "PhaseOffset should be an int or a float in [0,360)."

    AnotherIteration = True
    AttemptNumber = 1

    while AnotherIteration == True:
        X = np.zeros((8, N))
        InitialTension,InitialMuscleLengths,InitialActivations = \
         find_viable_initial_values(**kwargs)
        X[:, 0] = [
            r(0),
            dr(0), InitialTension[0][0], InitialTension[1][0],
            InitialMuscleLengths[0], InitialMuscleLengths[1], 0, 0
        ]
        U = np.zeros((2, N))
        if Amps == "Scaled":
            Amps = 0.25 * InitialActivations
        U[0, :] = InitialActivations[0] + Amps[0] * (
            np.cos(2 * np.pi * Freq * Time) - 1)
        U[1, :] = InitialActivations[1] + Amps[1] * (
            np.cos(2 * np.pi * Freq * Time - PhaseOffset *
                   (np.pi / 180)) - np.cos(-PhaseOffset * (np.pi / 180)))

        try:
            cprint("Attempt #" + str(int(AttemptNumber)) + ":\n", 'green')
            statusbar = dsb(0, N - 1, title=run_sim_FF_sinus_act.__name__)
            for i in range(N - 1):
                X[:,i+1] = X[:,i] + dt*np.array([ dX1_dt(X[:,i]),\
                         dX2_dt(X[:,i]),\
                         dX3_dt(X[:,i]),\
                         dX4_dt(X[:,i]),\
                         dX5_dt(X[:,i]),\
                         dX6_dt(X[:,i]),\
                         dX7_dt(X[:,i],U=U[:,i+1]),\
                         dX8_dt(X[:,i],U=U[:,i+1])
                                                    ])
                statusbar.update(i)
            AnotherIteration = False
            return (X, U)
        except:
            print('\n')
            print(" "*(get_terminal_width()\
               - len("...Attempt #" + str(int(AttemptNumber)) + " Failed. "))\
               + colored("...Attempt #" + str(int(AttemptNumber)) + " Failed. \n",'red'))
            AttemptNumber += 1
            if AttemptNumber > thresh:
                AnotherIteration = False
                return (np.zeros((8, N)), np.zeros((2, N)))
예제 #5
0
def run_N_sim_FF_sinus_act(**kwargs):
    """
    Runs one simulation for FEEDFORWARD SINUSOIDAL INPUT control.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    **kwargs
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    0) NumberOfTrials - positive integer value.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    **kwargs (Passed to run_sim_FF_sinus_act())
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    1) Bounds - must be a (2,2) list with each row in ascending order. Default is given by Tension_Bounds.

    2) InitialAngularAcceleration - must be a float or an int. Default is 0 (starting from rest).

    3) thresh - must be an int. Default is 25.

    4) FixedInitialTension - will be passed to find_viable_initial_values and will fix the value of initial tension. Must be a (2,) numpy.ndarray. Run find_initial_tension outside of the loop for a given seed and then feed it through the pipeline.

    5) Amps - list of length 2 that has the amplitudes of sinusoidal activation trajectories.

    6) Freq - scalar value given in Hz.

    7) PhaseOffset - scalar value in [0,360).

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    **kwargs (Passed to find_viable_initial_values())
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    8) InitialAngularAcceleration - must be either a numpy.float64, float, or int. Default is set to 0 to simulate starting from rest. Choice of reference trajectory *should* not matter as it is either 0 or d2r(0) (either by convention or by choice).

    9) InitialAngularSnap - must be either a numpy.float64, float, or int. Default is set to 0 to simulate starting from rest. Choice of reference trajectory *should* not matter as it is either 0 or d4r(0) (either by convention or by choice).

    """
    NumberOfTrials = kwargs.get("NumberOfTrials", 10)

    TotalX = np.zeros((NumberOfTrials, 8, N))
    TotalU = np.zeros((NumberOfTrials, 2, N))
    TerminalWidth = get_terminal_width()

    print("\n")
    for j in range(NumberOfTrials):
        TrialTitle = ("          Trial " + str(j + 1) + "/" +
                      str(NumberOfTrials) + "          \n")
        print(" " * int(TerminalWidth / 2 - len(TrialTitle) / 2) +
              colored(TrialTitle, 'white', attrs=["underline", "bold"]))
        TotalX[j], TotalU[j] = run_sim_FF_sinus_act(**kwargs)

    i = 0
    NumberOfSuccessfulTrials = NumberOfTrials
    while i < NumberOfSuccessfulTrials:
        if (TotalX[i] == np.zeros((8, np.shape(TotalX)[2]))).all():
            TotalX = np.delete(TotalX, i, 0)
            TotalU = np.delete(TotalU, i, 0)
            NumberOfSuccessfulTrials -= 1
            if NumberOfSuccessfulTrials == 0:
                raise ValueError("No Successful Trials!")
        else:
            i += 1

    print("Number of Desired Runs: " + str(NumberOfTrials) + "\n" +
          "Number of Successful Runs: " + str(NumberOfSuccessfulTrials) + "\n")
    return (TotalX, TotalU)
#     ReturnMultipleInitialTensions=True,
#     Bounds=[[0,0.4*F_MAX1],[0,0.4*F_MAX2]],
#     InitialAngularAcceleration=0
# ) # list of len::8
InitialTensions = return_initial_tension(X_o,
                                         ReturnMultipleInitialTensions=True,
                                         Seed=1,
                                         Bounds=[[0, 0.4 * BIC.F_MAX],
                                                 [0, 0.4 * TRI.F_MAX]],
                                         InitialAngularAcceleration=d2r(0),
                                         Return_k=False)  # list of len::8
InitialTensions = InitialTensions[3:6]
# InitialTensions = [InitialTensions[3]]
NumberOfTensionTrials = len(InitialTensions)
InitialTensionsFromSuccessfulTrials = []
TerminalWidth = get_terminal_width()
count = 0
for i in range(NumberOfTensionTrials):
    try:
        TensionTrialTitle = ("          Tension Setting " + str(i + 1) + "/" +
                             str(NumberOfTensionTrials) + "          \n")
        print(" " * int(TerminalWidth / 2 - len(TensionTrialTitle) / 2) +
              colored(TensionTrialTitle, 'blue', attrs=["underline", "bold"]))

        TotalX_temp, TotalU_temp = run_N_sim_IB_sinus_act(
            NumberOfTrials=1,
            FixedInitialTension=InitialTensions[i],
            Amp="Scaled",
            Freq=1,
            InitialAngularAcceleration=0,
            InitialAngularSnap=0)
def run_sim_IB_sinus_act(**kwargs):
    """
    Runs one simulation for INTEGRATOR BACKSTEPPING SINUSOIDAL INPUT control.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    **kwargs
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    1) Bounds - must be a (2,2) list with each row in ascending order. Default is given by Tension_Bounds.

    2) InitialAngularAcceleration - must be a float or an int. Default is 0 (starting from rest).

    3) thresh - must be an int. Default is 25.

    4) FixedInitialTension - will be passed to find_viable_initial_values and will fix the value of initial tension. Must be a (2,) numpy.ndarray. Run find_initial_tension outside of the loop for a given seed and then feed it through the pipeline.

    5) Amps - list of length 2 that has the amplitudes of sinusoidal activation trajectories.

    6) Freq - scalar value given in Hz.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    **kwargs (Passed to find_viable_initial_values())
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    7) InitialAngularAcceleration - must be either a numpy.float64, float, or int. Default is set to 0 to simulate starting from rest. Choice of reference trajectory *should* not matter as it is either 0 or d2r(0) (either by convention or by choice).

    8) InitialAngularSnap - must be either a numpy.float64, float, or int. Default is set to 0 to simulate starting from rest. Choice of reference trajectory *should* not matter as it is either 0 or d4r(0) (either by convention or by choice).

    9) FixedInitialMuscleLengths - must be a list of length 2 or None (Default). If is None, then program will assign this value randomly. Used for trials where we wish to hold muscle length constant for different tension levels.

    """

    thresh = kwargs.get("thresh", 25)
    assert type(
        thresh
    ) == int, "thresh should be an int as it is the number of attempts the program should run before stopping."

    Bounds = kwargs.get("Bounds", Activation_Bounds)
    assert type(Bounds) == list and np.shape(Bounds) == (
        2, 2), "Bounds should be a list of shape (2,2)."

    Amp = kwargs.get("Amp", 1)
    PhaseOffset = kwargs.get("PhaseOffset", 0)
    if Amp != "Scaled":
        assert type(Amp) in [int, float], "Amp should be an int or a float."

    Freq = kwargs.get("Freq", 1)
    assert type(Freq) in [int, float], "Freq should be an int or a float."

    AnotherIteration = True
    AttemptNumber = 1

    while AnotherIteration == True:
        X = np.zeros((8, N))
        InitialTension,InitialMuscleLengths,InitialActivations = \
         find_viable_initial_values(**kwargs)
        X[:, 0] = [
            r(0),
            dr(0), InitialTension[0][0], InitialTension[1][0],
            InitialMuscleLengths[0], InitialMuscleLengths[1], 0, 0
        ]
        U = np.zeros((2, N))
        if Amp is "Scaled":
            Amp = 0.25 * InitialActivations[0]
        assert Amp > 0, "Amp became negative. Run Again."
        # import ipdb; ipdb.set_trace()

        newBase = InitialActivations[0] - Amp * (np.cos(PhaseOffset) - 1)
        U[0, :] = newBase + Amp * (
            np.cos(2 * np.pi * Freq * Time + PhaseOffset) - 1)
        U[1, 0] = InitialActivations[1]
        # U[0,:] = InitialActivations[0] + Amp*(np.cos(2*np.pi*Freq*Time+PhaseOffset)-1)
        # U[1,0] = InitialActivations[1]

        try:
            cprint("Attempt #" + str(int(AttemptNumber)) + ":\n", 'green')
            statusbar = dsb(0, N - 1, title=run_sim_IB_sinus_act.__name__)
            for i in range(N - 1):
                U[:, i + 1] = return_U_given_sinusoidal_u1(
                    i, Time, X[:, i], U[0, i + 1])
                X[:,i+1] = X[:,i] + dt*np.array([ dX1_dt(X[:,i]),\
                         dX2_dt(X[:,i]),\
                         dX3_dt(X[:,i]),\
                         dX4_dt(X[:,i]),\
                         dX5_dt(X[:,i]),\
                         dX6_dt(X[:,i]),\
                         dX7_dt(X[:,i],U=U[:,i+1]),\
                         dX8_dt(X[:,i],U=U[:,i+1])
                                                    ])
                statusbar.update(i)
            AnotherIteration = False
            return (X, U)
        except:
            print('\n')
            print(" "*(get_terminal_width()\
               - len("...Attempt #" + str(int(AttemptNumber)) + " Failed. "))\
               + colored("...Attempt #" + str(int(AttemptNumber)) + " Failed. \n",'red'))
            AttemptNumber += 1
            if AttemptNumber > thresh:
                AnotherIteration = False
                return (np.zeros((8, N)), np.zeros((2, N)))
def run_sim_gauss_act(**kwargs):
    """
    Runs one simulation for NEARBY ACTIVATION BY GAUSSIAN DISTRIBUTION control.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    **kwargs
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    1) Bounds - must be a (2,2) list with each row in ascending order. Default is given by Tension_Bounds.

    2) InitialAngularAcceleration - must be a float or an int. Default is 0 (starting from rest).

    3) thresh - must be an int. Default is 25.

    4) FixedInitialTension - will be passed to find_viable_initial_values and will fix the value of initial tension. Must be a (2,) numpy.ndarray. Run find_initial_tension outside of the loop for a given seed and then feed it through the pipeline.

    """
    thresh = kwargs.get("thresh",25)
    assert type(thresh)==int, "thresh should be an int as it is the number of attempts the program should run before stopping."

    AnotherIteration = True
    AttemptNumber = 1

    while AnotherIteration == True:
        X = np.zeros((8,N))
        InitialTension,InitialMuscleLengths,InitialActivations = \
        	find_viable_initial_values(**kwargs)
        X[:,0] = [
        	r(0),
        	dr(0),
        	InitialTension[0][0],
        	InitialTension[1][0],
        	InitialMuscleLengths[0],
        	InitialMuscleLengths[1],
        	0,
        	0]
        U = np.zeros((2,N))
        U[:,0] = InitialActivations

        AddNoise = False
        if AddNoise == True:
            np.random.seed(seed=None)
            NoiseArray = np.random.normal(loc=0.0,scale=0.2,size=(2,N))
        else:
            NoiseArray = np.zeros((2,N))

        try:
            cprint("Attempt #" + str(int(AttemptNumber)) + ":\n", 'green')
            statusbar = dsb(0,N-1,title=run_sim_gauss_act.__name__)
            for i in range(N-1):
                U[:,i+1] = return_U_gaussian_activations_nearby(i,Time,X[:,i],U[:,i],Noise = NoiseArray[:,i])
                X[:,i+1] = X[:,i] + dt*np.array([	dX1_dt(X[:,i]),\
                									dX2_dt(X[:,i]),\
                									dX3_dt(X[:,i]),\
                									dX4_dt(X[:,i]),\
                									dX5_dt(X[:,i]),\
                									dX6_dt(X[:,i]),\
                									dX7_dt(X[:,i],U=U[:,i+1]),\
                									dX8_dt(X[:,i],U=U[:,i+1])
                                                    ])
                statusbar.update(i)
            AnotherIteration = False
            return(X,U)
        except:
            print('\n')
            print(" "*(get_terminal_width()\
            			- len("...Attempt #" + str(int(AttemptNumber)) + " Failed. "))\
            			+ colored("...Attempt #" + str(int(AttemptNumber)) + " Failed. \n",'red'))
            AttemptNumber += 1
            if AttemptNumber > thresh:
                AnotherIteration=False
                return(np.zeros((8,N)),np.zeros((2,N)))
def run_sim_IB_sinus_act(**kwargs):
    """
    Runs one simulation for INTEGRATOR BACKSTEPPING SINUSOIDAL INPUT control.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    **kwargs
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    1) Bounds - must be a (2,2) list with each row in ascending order. Default is given by Tension_Bounds.

    2) InitialAngularAcceleration - must be a float or an int. Default is 0 (starting from rest).

    3) thresh - must be an int. Default is 25.

    4) FixedInitialTension - will be passed to find_viable_initial_values and will fix the value of initial tension. Must be a (2,) numpy.ndarray. Run find_initial_tension outside of the loop for a given seed and then feed it through the pipeline.

    5) Amps - list of length 2 that has the amplitudes of sinusoidal activation trajectories.

    6) Freq - scalar value given in Hz.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    **kwargs (Passed to initialize_tendon_tension())
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    7) ReturnMultipleInitialTensions - must be either True or False. Default is False.

    8) Seed - must be a float or an int. Default is None (seeded by current time).

    9) Return - must be either true or false (default). When false, function will assign the initial tension value to self.

    10) TensionBounds - must be a list of size (2,2) or None (in which case the self.TensionBounds will be used)

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    **kwargs (Passed to find_viable_initial_values())
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    11) FixedInitialMuscleLengths - must be a list of length 2 or None (Default). If is None, then find_viable_initial_values() will assign this value randomly. Used for trials where we wish to hold muscle length constant for different tension levels.

    12) Seed - must be a float or an int. Default is None (seeded by current time).

    """

    thresh = kwargs.get("thresh",25)
    assert type(thresh)==int, "thresh should be an int as it is the number of attempts the program should run before stopping."

    Bounds = kwargs.get("Bounds",Activation_Bounds)
    assert type(Bounds)==list and np.shape(Bounds)==(2,2), "Bounds should be a list of shape (2,2)."

    Amp = kwargs.get("Amp",1)
    if Amp is not "Scaled":
        assert type(Amp) in [int,float], "Amp should be an int or a float."

    Freq = kwargs.get("Freq",1)
    assert type(Freq) in [int,float], "Freq should be an int or a float."

    ICs = kwargs.get("ICs",None)

    TensionBounds = kwargs.get("TensionBounds",None)
    Seed = kwargs.get("Seed",None)

    AnotherIteration = True
    AttemptNumber = 1

    while AnotherIteration == True:
        Plant = Pendulum_1DOF_2DOA(BIC,TRI,Time)
        # should combine to one function now.
        Plant.initialize_tendon_tension(
            Seed=Seed,
            Bounds=TensionBounds
        )
        if ICs is None:
            Plant.find_viable_initial_values(**kwargs)
            Plant.set_X_o()
            Plant.set_U_o()
        else:
            assert ((len(ICs)==2)
                    and (np.shape(ICs[0])==(8,))
                    and (np.shape(ICs[1])==(2,))), \
                "ICs must be a list that contains X_o (of shape (8,)) and U_o (of shape (2,))."
            Plant.set_X_o(ICs[0])
            Plant.set_U_o(ICs[1])

        U = np.zeros((2,N))
        if Amp is "Scaled":
            Amp = 0.75*Plant.U_o[0]
            # Amp1 = 0.1
            # Amp2 = 0.50*InitialActivations[0]
            # assert InitialActivations[0]<0.15, "InitialActivations too high."
            # Amp2 = 0.6
        # assert (Amp1>=0) and (Amp2>=0), "Amp became negative. Run Again."
        assert Amp>0, "Amp became negative. Run Again."

        # phase1 = np.ones(np.shape(Time))*(np.array([np.sin(2*np.pi*Time)])>0)
        # phase2 = np.ones(np.shape(Time))*(np.array([np.sin(2*np.pi*Time)])<=0)
        # U[0,:] = (
        #     InitialActivations[0]
        #     + (Amp1*(1-np.cos(4*np.pi*Time))/2)*phase1
        #     + (Amp2*(1-np.cos(4*np.pi*Time))/2)*phase2
        # )
        # U[0,:] = U[0,:]*(U[0,:]>=0)
        # import ipdb; ipdb.set_trace()
        shift = 3*np.pi/16
        U[0,:] = (
            Plant.U_o[0]
            - Amp*np.sin(2*np.pi*Freq*Time+shift)
        )
        # U[0,:] = InitialActivations[0] + Amp*(1-np.cos(4*np.pi*Freq*Time))/2
        U[1,0] = Plant.U_o[1]
        U_o = U[:,0]
        #########
        # Plant = Pendulum_1DOF_2DOA(BIC,TRI,X_o,U_o,Time)
        Plant.U[0,:] = U[0,:]
        try:
            cprint("Attempt #" + str(int(AttemptNumber)) + ":\n", 'green')
            statusbar = dsb(0,N-1,title=run_sim_IB_sinus_act.__name__)
            for i in range(N-1):
                Plant.update_pendulum_variables(i)
                Plant.forward_integrate(i)
                statusbar.update(i)

            AnotherIteration = False
            return(Plant.X,Plant.U)
        except:
            print('\n')
            print(" "*(get_terminal_width()\
            			- len("...Attempt #" + str(int(AttemptNumber)) + " Failed. "))\
            			+ colored("...Attempt #" + str(int(AttemptNumber)) + " Failed. \n",'red'))
            AttemptNumber += 1
            if AttemptNumber > thresh:
                AnotherIteration=False
                return(np.zeros((8,N)),np.zeros((2,N)))