def pendulum_integration(state, time, *args): """ Function for system integration """ pylog.warning("Pendulum equation with spring and damper must be implemented") # _S pendulum = args[0] return pendulum.pendulum_system( state[0], state[1], time, torque=0.0 )[:, 0]
def add_mass(self, mass): """Add the mass to the system. Parameters ---------- mass: <Mass> Instance of mass model Example: -------- >>> from mass import Mass >>> from system_parameters import MassParameters >>> mass = Muscle(MassParameters()) #: Default mass >>> isotonic_system = IsotonicMuscleSystem() >>> isotonic_system.add_muscle(muscle) """ if self.mass is not None: pylog.warning( 'You have already added the mass model to the system.') return else: if mass.__class__ is not Mass: pylog.error('Trying to set of type {} to mass'.format( mass.__class__)) raise TypeError() else: pylog.info('Added new mass model to the system') self.mass = mass
def __init__(self, parameters=None): super(Mass, self).__init__() if parameters is None: pylog.warning('Setting default parameters to mass model.') self.parameters = MassParameters() else: self.parameters = parameters
def isMagic(M): r = np.size(M, 0) c = np.size(M, 1) if (r == c): magic_num = np.sum(M, 1)[0] for x in range(0, r - 1): row_sum = 0 col_sum = 0 udiag_sum = 0 ldiag_sum = 0 for y in range(0, r - 1): #check rows: row_sum += M[x, y] #check columns: col_sum += M[y, x] #check upper diagonals: udiag_sum += M[(x + y) % r, (y) % r] #check lower diagonals: ldiag_sum += M[(x + y) % r, (r - y - 1)] break if (row_sum != magic_num) or (col_sum != magic_num) or ( udiag_sum != magic_num) or (ldiag_sum != magic_num): return 'not magic' break return 'is magic!' else: #return error Not square pylog.warning('Matrix is not square') return 'not magic'
def set_frequencies(self, parameters): """Set frequencies""" freqs = np.ones(self.n_oscillators) freq_body = 0 freq_limb = 0 d_high = 5.0 d_low = 1.0 if self.drive >= d_low and self.drive <= d_high: freq_body = 0.2 * self.drive + 0.3 d_high = 3.0 if self.drive >= d_low and self.drive <= d_high: freq_limb = 0.2 * self.drive freqs[:20] = freq_body freqs[20:] = freq_limb self.freqs = freqs #pylog.warning("Coupling weights must be set") pylog.warning(self.freqs)
def pendulum_equation(theta, dtheta, time=0, parameters=None, torque=0.): """ Pendulum equation with: - theta: Angle [rad] - dtheta: Angular velocity [rad/s] - g: Gravity constant [m/s**2] - m: Mass [kg] - L: Length [m] - d: Damping coefficient [] - torque: External torque [N-m] """ if parameters is None: parameters = PendulumParameters() pylog.warning( "Parameters not given, using defaults\n{}".format(parameters)) g, m, L, I, d, sin, dry = (parameters.g, parameters.m, parameters.L, parameters.I, parameters.d, parameters.sin, parameters.dry) if dry: return -(g / L) * sin(theta) - d * np.sign(dtheta) + torque / m else: return -(g / L) * sin(theta) - d * dtheta + torque / m
def add_muscle(self, muscle): """Add the muscle to the system. Parameters ---------- muscle: <Muscle> Instance of muscle model Example: -------- >>> from muscle import Muscle >>> from system_parameters import MuscleParameters >>> muscle = Muscle(MuscleParameters()) #: Default muscle >>> isotonic_system = IsotonicMuscleSystem() >>> isotonic_system.add_muscle(muscle) """ if self.muscle is not None: pylog.warning( 'You have already added the muscle model to the system.') return else: if muscle.__class__ is not Muscle: pylog.error('Trying to set of type {} to muscle'.format( muscle.__class__)) raise TypeError() else: pylog.info('Added new muscle model to the system') self.muscle = muscle
def run_network(duration, update=False, drive=0): """Run network without Webots and plot results""" # Simulation setup timestep = 5e-3 times = np.arange(0, duration, timestep) n_iterations = len(times) parameter_set = SimulationParameters( simulation_duration=100, drive_mlr=2.5, phase_lag=2 * np.pi / 10, ) network = SalamanderNetwork(timestep, parameter_set) osc_left = np.arange(10) osc_right = np.arange(10, 20) osc_legs = np.arange(20, 24) # Logs phases_log = np.zeros([n_iterations, len(network.state.phases)]) phases_log[0, :] = network.state.phases amplitudes_log = np.zeros([n_iterations, len(network.state.amplitudes)]) amplitudes_log[0, :] = network.state.amplitudes freqs_log = np.zeros([n_iterations, len(network.parameters.freqs)]) freqs_log[0, :] = network.parameters.freqs outputs_log = np.zeros( [n_iterations, len(network.get_motor_position_output())]) outputs_log[0, :] = network.get_motor_position_output() # Run network ODE and log data tic = time.time() for i, _ in enumerate(times[1:]): if update: network.parameters.update( SimulationParameters( drive_mlr=2 # amplitude_gradient=None, # phase_lag=None )) network.step() phases_log[i + 1, :] = network.state.phases amplitudes_log[i + 1, :] = network.state.amplitudes outputs_log[i + 1, :] = network.get_motor_position_output() freqs_log[i + 1, :] = network.parameters.freqs toc = time.time() # Network performance pylog.info("Time to run simulation for {} steps: {} [s]".format( n_iterations, toc - tic)) # Implement plots of network results pylog.warning("Implement plots") #plot_results.main(plot=True) #plt.plot(phases_log) plt.close('all') plt.figure('a') plt.plot(outputs_log) plt.figure('b') plt.plot(amplitudes_log)
def rk4(ode, timestep, time, state, *parameters): """ODE solver with Runge-Kutta method""" k_1 = timestep * ode(time, state, *parameters) pylog.warning(np.shape(k_1)) k_2 = timestep * ode(time + 0.5 * timestep, state + 0.5 * k_1, *parameters) k_3 = timestep * ode(time + 0.5 * timestep, state + 0.5 * k_2, *parameters) k_4 = timestep * ode(time + timestep, state + k_3, *parameters) return (k_1 + 2 * k_2 + 2 * k_3 + k_4) / 6
def set_parameters(self, freqs, phase_lag): """Set parameters of the network""" # Set coupling weights pylog.warning("Coupling weights must be set") # Set desired phases pylog.warning("Desired phases must be set")
def set_parameters(self, amplitudes, turn): """Set parameters of the network""" # Set convergence rates pylog.warning("Convergence rates must be set") # Set desired amplitudes pylog.warning("Desired amplitudes must be set")
def k2(self, value): """ Keyword Arguments: value -- Set the value of spring constant for spring 2[N/rad] """ if (value < 0.0): pylog.warning('Setting bad spring constant. Should be positive!') else: self.parameters['k2'] = value pylog.info('Changed spring constant of spring 1 to {} [N/rad]'.format( self.parameters['k2']))
def b2(self, value): """ Keyword Arguments: value -- Set the value of damping constant for damper 2. [N-s/rad] """ if (value < 0.0): pylog.warning('Setting bad damping values. Should be positive!') else: self.parameters['b2'] = value pylog.info( 'Changed damping constant for damper 2 to {} [N-s/rad]'.format(self.parameters['b2']))
def run_network(duration, update=False, drive=0): """Run network without Webots and plot results""" # Simulation setup timestep = 5e-3 times = np.arange(0, duration, timestep) n_iterations = len(times) parameters = SimulationParameters( drive=drive, amplitude_gradient=None, phase_lag=None, turn=1.0, use_drive_saturation=1, shes_got_legs=1, cR_body=[0.05, 0.16], #cR1, cR0 cR_limb=[0.131, 0.131], #cR1, cR0 amplitudes_rate=40, ) network = SalamanderNetwork(timestep, parameters) osc_left = np.arange(10) osc_right = np.arange(10, 20) osc_legs = np.arange(20, 24) # Logs phases_log = np.zeros([n_iterations, len(network.state.phases)]) phases_log[0, :] = network.state.phases amplitudes_log = np.zeros([n_iterations, len(network.state.amplitudes)]) amplitudes_log[0, :] = network.state.amplitudes freqs_log = np.zeros([n_iterations, len(network.parameters.freqs)]) freqs_log[0, :] = network.parameters.freqs outputs_log = np.zeros( [n_iterations, len(network.get_motor_position_output())]) outputs_log[0, :] = network.get_motor_position_output() # Run network ODE and log data tic = time.time() for i, _ in enumerate(times[1:]): if update: network.parameters.update( SimulationParameters( # amplitude_gradient=None, # phase_lag=None )) network.step() phases_log[i + 1, :] = network.state.phases amplitudes_log[i + 1, :] = network.state.amplitudes outputs_log[i + 1, :] = network.get_motor_position_output() freqs_log[i + 1, :] = network.parameters.freqs toc = time.time() # Network performance pylog.info("Time to run simulation for {} steps: {} [s]".format( n_iterations, toc - tic)) # Implement plots of network results pylog.warning("Implement plots") plot_results.main()
def exercise1(clargs): """ Exercise 1 """ # Setup pylog.info("Running exercise 1") # Setup time_max = 5 # Maximum simulation time time_step = 0.2 # Time step for ODE integration in simulation x0 = np.array([1.]) # Initial state # Integration methods (Exercises 1.a - 1.d) pylog.info("Running function integration using different methods") # Example pylog.debug("Running example plot for integration (remove)") example = example_integrate(x0, time_max, time_step) example.plot_state(figure="Example", label="Example", marker=".") # Analytical (1.a) time = np.arange(0, time_max, time_step) # Time vector x_a = analytic_function(time) analytical = Result(x_a, time) if x_a is not None else None # Euler (1.b) euler = euler_integrate(function, x0, time_max, time_step) # ODE (1.c) ode = ode_integrate(function, x0, time_max, time_step) # ODE Runge-Kutta (1.c) ode_rk = ode_integrate_rk(function_rk, x0, time_max, time_step) # Euler with lower time step (1.d) pylog.warning("Euler with smaller ts must be implemented") euler_time_step = None euler_ts_small = (euler_integrate(function, x0, time_max, euler_time_step) if euler_time_step is not None else None) # Plot integration results plot_integration_methods(analytical=analytical, euler=euler, ode=ode, ode_rk=ode_rk, euler_ts_small=euler_ts_small, euler_timestep=time_step, euler_timestep_small=euler_time_step) # Error analysis (Exercise 1.e) pylog.warning("Error analysis must be implemented") # Show plots of all results if not clargs.save_figures: plt.show() return
def exercise_9c(world, timestep, reset): """Exercise 9c""" # Parameters outfile = TemporaryFile() parameter_set = [ [ SimulationParameters( simulation_duration=20, drive=4.5, amplitude_gradient=[head, tail], phase_lag=2 * np.pi / 10, # ... ) for head in np.linspace(0.1, 1.5, 15) ] for tail in np.linspace(0.1, 1.5, 15) ] # for amplitudes in ... pylog.warning(np.shape(parameter_set)) head = np.linspace(0.1, 1.5, 15) tail = np.linspace(0.1, 1.5, 15) pylog.warning(head) energy = np.zeros((len(head), len(tail))) for i in range(0, len(head)): for j in range(0, len(tail)): reset.reset() parameters = parameter_set[i][j] run_simulation( world, parameters, timestep, int(1000 * parameters.simulation_duration / timestep), logs="./logs/simulation9c_more_head{}_tail{}.npz".format( head[i], tail[j])) data = np.load("logs/simulation9c_more_head{}_tail{}.npz".format( head[i], tail[j])) velocity = np.diff(data["joints"][:, :, 0], axis=0) / timestep velocity = np.insert(velocity, 0, 0, axis=0) torque = data["joints"][:, :, 2] energy[i, j] = np.mean(np.trapz(velocity * torque, dx=timestep)) np.save(outfile, energy) outfile.seek(0) #for when you want to open it again plt.imshow(energy, extent=[0.1, 1, 0.1, 1]) plt.xlabel('head factor') plt.ylabel('tail factor') plt.title('Energy estimation') plt.colorbar() plt.show()
def pendulum_system(self, time, theta, dtheta, torque): """ Pendulum System. Accessor method adding pertrubtions.""" # YOU CAN ADD PERTURBATIONS TO THE PENDULUM MODEL HERE if self.parameters.PERTURBATION is True: if 1.2 < time < 1.25: pylog.warning('Perturbing the pendulum') torque += 100 return np.array([ [dtheta], [self.pendulum_equation(theta, dtheta, torque)] # d2theta ])[:, 0]
def add_muscle(self, muscle): if self.muscle is not None: pylog.warning( 'You have already added the muscle model to the system.') return else: if muscle.__class__ is not Muscle: pylog.error('Trying to set of type {} to muscle'.format( muscle.__class__)) raise TypeError() else: pylog.info('Added new muscle model to the system') self.muscle = muscle
def add_pendulum_system(self, system): """Add the pendulum system. Parameters ---------- system: Pendulum Pendulum system """ if self.systems_list.count('pendulum') == 1: pylog.warning( 'You have already added the pendulum model to the system.') return else: pylog.info('Added pedulum model to the system') self.systems_list.append('pendulum') self.pendulum_sys = system
def add_muscle_system(self, system): """Add the muscle system. Parameters ---------- system: MuscleSystem Muscle system """ if self.systems_list.count('muscle') == 1: pylog.warning( 'You have already added the muscle model to the system.') return else: pylog.info('Added muscle model to the system') self.systems_list.append('muscle') self.muscle_sys = system
def add_neural_system(self, system): """Add the neural network system. Parameters ---------- system: NeuralSystem Neural Network system """ if self.systems_list.count('neural') == 1: pylog.warning( 'You have already added the neural model to the system.') return else: pylog.info('Added neural network to the system') self.systems_list.append('neural') self.neural_sys = system
def exercise5(): """ Lab 3 - Exrecise 5 """ # Fixed parameters of the neural network tau = [0.05, 0.05] D = 1 # Additional parameters b = [0, 0] w = [[1, 0], [0, 1]] # All system parameters packed in object for integration params = LeakyIntegratorParameters(tau, D, b, w) # Initial conditions y_0 = [[0, 0]] # Values of the membrane potentials of the two neurons dt = 1e-4 t_max = 30 # Set total simulation time # Integration (make sure to implement) two_coupled_li_neurons(y_0, t_max, dt, params, "Case1") # Two stable fixed points and one saddle node pylog.warning("Implement two stable fixed points and one saddle node") tau = [1, 1] D = 1 b = [-3.4, -2.5] w = [[5.25, -1], [1, 5.25]] # All system parameters packed in object for integration params = LeakyIntegratorParameters(tau, D, b, w) y_0 = [[0, 0]] # Values of the membrane potentials of the two neurons two_coupled_li_neurons(y_0, t_max, dt, params, "Case2") # Limit cycle """ pylog.warning("Implement limit cycle") """ tau = [0.1, 0.1] D = 1 b = [-2.75, -1.75] w = [[4.5, -1], [1, 4.5]] # All system parameters packed in object for integration params = LeakyIntegratorParameters(tau, D, b, w) y_0 = [[0, 0]] # Values of the membrane potentials of the two neurons two_coupled_li_neurons(y_0, t_max, dt, params, "Case3") pylog.warning(u"Implement Poincare analysis of limit cycle") # Limit cycle (small), one stable fixed point and one saddle node pylog.warning("Implement a system with:" "\n- One limit cycle (small)" "\n- One stable fixed point" "\n- One saddle node") pylog.warning(u"Implement Poincare analysis of limit cycle") if DEFAULT["save_figures"] is False: plt.show() return
def ode_integrate(fun, x0, time_max, time_step): """ Integrate function using Euler method - fun: Function df/dt = f(x, t) to integrate - x0: Initial state - time_tot: Total time to simulate [s] - time_step: Time step [s] Use odeint from the scipy library for integration Make sure to then use the Result class similarly to the example_integrate found above (i.e. Result(x, time)) """ time = np.arange(0, time_max, time_step) # COMPLETE CODE pylog.warning("ODE integration must be implemented") return None
def euler_integrate(fun, x0, time_max, time_step): """ Integrate function using Euler method - fun: Function df/dt = f(x, t) to integrate - x0: Initial state - time_tot: Total time to simulate [s] - time_step: Time step [s] For loop in Python: >>> a = [0, 0, 0] # Same as [0 for _ in range(3)] (List comprehension) >>> for i in range(3): ... a[i] = i >>> print(a) [0, 1, 2] Creating a matrix of zeros in python: >>> state = np.zeros([3, 2]) >>> print(state) [[0. 0.] [0. 0.] [0. 0.]] For loop for a state in python >>> state = np.zeros([3, 2]) >>> state[0, 0], state[0, 1] = 1, 2 >>> for i, time in enumerate([0, 0.1, 0.2]): ... state[i, 0] += time ... state[i, 1] -= time >>> print(state) [[ 1. 2. ] [ 0.1 -0.1] [ 0.2 -0.2]] Make sure to use the Result class similarly to the example_integrate found above (i.e. Result(x, time)) """ time = np.arange(0, time_max, time_step) x = np.zeros([len(time), len(x0)]) # COMPLETE CODE pylog.warning("Euler integration must be implemented") return None
def exercise5(): """ Lab 3 - Exrecise 5 """ # Fixed parameters of the neural network tau = [0.1, 0.1] D = 1 # Additional parameters b = [-2.75, -1.75] w = [[4.5, -1], [1, 4.5]] # All system parameters packed in object for integration params = LeakyIntegratorParameters(tau, D, b, w) # Initial conditions # SET THE INITIAL CONDITIONS y_0 = [[0, 0]] # Values of the membrane potentials of the two neurons # Integration time parameters # Force integration to return values at small steps for # better detecting Poincare maps crossings dt = 1e-4 t_max = 30 # Set total simulation time # Integration (make sure to implement) two_coupled_li_neurons(y_0, t_max, dt, params, "Case1") # Two stable fixed points and one saddle node pylog.warning("Implement two stable fixed points and one saddle node") # Limit cycle pylog.warning("Implement limit cycle") pylog.warning("Implement Poincare analysis of limit cycle") # Limit cycle (small), one stable fixed point and one saddle node pylog.warning("Implement a system with:" "\n- One limit cycle (small)" "\n- One stable fixed point" "\n- One saddle node") pylog.warning(u"Implement Poincare analysis of limit cycle") if DEFAULT["save_figures"] is False: plt.show() return
def save_figure(figure, name=None): """ Save figure """ if os.path.isdir(DEFAULT["save_folder"]): path = DEFAULT["save_folder"] else: pylog.warning( "The DEFAULT save directory does not exist. Switching to current directory" ) path = os.getcwd() if DEFAULT["save_figures"]: for extension in DEFAULT["save_extensions"]: fig = figure.replace(" ", "_").replace(".", "dot") if name is None: name = "{}.{}".format(fig, extension) else: name = "{}.{}".format(name, extension) plt.savefig(path + name, bbox_inches='tight') pylog.debug("Saving figure {}...".format(name))
def name(self, animal_name): """ Parameters ---------- animal_name : <str> Name of the animal. If it is not a string then a warning is thrown Returns ------- out : None """ # Check if animal is a string or not if not isinstance(animal_name, str): pylog.warning( 'You don\'t really know how to name your animals! ') # This also works and is useful for dealing with inheritance: if not isinstance(animal_name, str): pylog.warning( 'You don\'t really know how to name your animals! (isinstance)') self._name = animal_name
def ode_integrate_rk(fun_rk, x0, time_max, time_step): """ Integrate function using Euler method - fun: Function df/dt = f(x, t) to integrate - x0: Initial state - time_tot: Total time to simulate [s] - time_step: Time step [s] For Runge-Kutta, use: solver = ode(fun) solver.set_integrator('dopri5') solver.set_initial_value(x0, time[0]) xi = solver.integrate(ti) Note that solver.integrate(ti) only integrates for one time step at time ti (where ti is the current time), so you will need to use a for loop Make sure to use the Result class similarly to the example_integrate found above (i.e. Result(x, time)) """ time = np.arange(0, time_max, time_step) # COMPLETE CODE pylog.warning("ODE integration with RK must be implemented") return None
def exercise3(clargs): """ Exercise 3 """ parameters = PendulumParameters() # Checkout pendulum.py for more info pylog.info(parameters) # Simulation parameters time = np.arange(0, 30, 0.01) # Simulation time x0 = [0.1, 0.0] # Initial state # To use/modify pendulum parameters (See PendulumParameters documentation): # parameters.g = 9.81 # Gravity constant # parameters.m = 1. # Mass # parameters.L = 1. # Length # parameters.I = 1. # Inertia (Automatically computed!) # parameters.d = 0.3 # damping # parameters.sin = np.sin # Sine function # parameters.dry = False # Use dry friction (True or False) # Example of system integration (Similar to lab1) # (NOTE: pendulum_equation must be imlpemented first) pylog.debug("Running integration example") res = integrate(pendulum_system, x0, time, args=(parameters,)) res.plot_state("State") res.plot_phase("Phase") # Evolutions # Write code here (You can add functions for the different cases) pylog.warning( "Evolution of pendulum in normal conditions must be implemented" ) pylog.warning( "Evolution of pendulum without damping must be implemented" ) pylog.warning( "Evolution of pendulum with perturbations must be implemented" ) pylog.warning( "Evolution of pendulum with dry friction must be implemented" ) # Show plots of all results if not clargs.save_figures: plt.show()
def exercise2(clargs): """ Exercise 2 """ pylog.info("Running exercise 2") # System definition pylog.warning("Proper matrix A must be implemented") A = np.array([[1, 0], [0, 1]]) time_total = 10 time_step = 0.01 x0, time = [0, 1], np.arange(0, time_total, time_step) # Normal run pylog.warning("System integration must be implemented") # integration(x0, time, A, "example") # Stable point (Optional) pylog.warning("Stable point integration must be implemented") # Periodic pylog.warning("Periodic system must be implemented") # Plot if not clargs.save_figures: plt.show()