def calc(a, b, op='add'): if op == 'add': return a + b elif op == 'sub': return a - b else: pylog.info('valid operations are add and sub')
def exercise2(clargs): """ Exercise 2 """ pylog.info("Running exercise 2") # System definition A = np.array([[1, 4], [-4, -2]]) time_total = 10 time_step = 0.01 x0, time = [0, 1], np.arange(0, time_total, time_step) # Normal run integration(x0, time, A, "Normal run") # Stable point (Optional) x0 = [0, 0] integration(x0, time, A, "x0 Fixed point") # Periodic A = np.array([[2, 4], [-4, -2]]) x0 = [1, 0] integration(x0, time, A, "Periodic") # Plot if not clargs.save_figures: plt.show()
def set_nominal_amplitudes(self, parameters): """Set nominal amplitudes""" nominal_amplitudes = np.zeros(self.n_oscillators) amp_body = 0 amp_limb = 0 d_high = 5.0 d_low = 1.0 if self.drive >= d_low and self.drive <= d_high: amp_body = 0.065 * self.drive + 0.196 d_high = 3.0 if self.drive >= d_low and self.drive <= d_high: amp_limb = 0.131 * self.drive + 0.131 gradient = np.linspace(self.amplitude_gradient[0], self.amplitude_gradient[1], 10) pylog.info(np.shape(gradient)) gradient_ = np.concatenate((gradient, gradient)) pylog.info(np.shape(gradient_)) nominal_amplitudes[:20] = amp_body * gradient_ nominal_amplitudes[20:] = amp_limb if (self.turn[1] == 'right' or self.turn[1] == 'Right'): nominal_amplitudes[ 10:20] = nominal_amplitudes[10:20] * self.turn[0] elif (self.turn[1] == 'left' or self.turn[1] == 'Left'): nominal_amplitudes[0:10] = nominal_amplitudes[0:10] * self.turn[0] self.nominal_amplitudes = self.amp_factor * nominal_amplitudes
def run_simulation(world, parameters, timestep, n_iterations, logs): """Run simulation""" # Set parameters pylog.info(( "Running new simulation:" "\n - Amplitude: {}" "\n - Phase lag: {}" "\n - Turn: {}" ).format(parameters[0], parameters[1], parameters[2])) # Setup salamander control salamander = SalamanderCMC( world, n_iterations, logs=logs, freqs=parameters[0], amplitudes=parameters[1], phase_lag=parameters[2], turn=parameters[3] ) # Simulation iteration = 0 while world.step(timestep) != -1: iteration += 1 if iteration >= n_iterations: break salamander.step() # Log data pylog.info("Logging simulation data to {}".format(logs)) salamander.log.save_data()
def main(): """Main function that runs all the exercises.""" pylog.info('Implementing Lab 6 : Exercise 2') exercise2() pylog.info('Implementing Lab 6 : Exercise 3') exercise3() return
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 main(): """Main""" # Duration of each simulation simulation_duration = 20 # Get supervisor to take over the world world = Supervisor() n_joints = 10 timestep = int(world.getBasicTimeStep()) freqs = 1 # Get and control initial state of salamander reset = RobotResetControl(world, n_joints) # Simulation example amplitude = None phase_lag = None turn = None parameter_set = [[freqs, amplitude, phase_lag, turn], [freqs, amplitude, phase_lag, turn]] for simulation_i, parameters in enumerate(parameter_set): reset.reset() run_simulation( world, parameters, timestep, int(1000 * simulation_duration / timestep), logs="./logs/example/simulation_{}.npz".format(simulation_i)) # Pause world.simulationSetMode(world.SIMULATION_MODE_PAUSE) pylog.info("Simulations complete") world.simulationQuit(0)
def validate_muscle_attachment(self, parameters): """Validate the muscle attachment positions. Provided pendulum length and muscle attachments check if the muscle attachments are valid or not! Parameters ---------- parameters: PendulumParameters Pendulum parameters Returns ------- check : bool Returns if the muscle attachments are valid or not """ check = (parameters.L > abs(self.muscle1_pos[1, 1])) and ( parameters.L > abs(self.muscle2_pos[1, 1])) and ( self.muscle1_pos[1, 0] == 0.0) and (self.muscle2_pos[1, 0] == 0.0) if check: pylog.info('Validated muscle attachments') return check pylog.error('Invalid muscle attachment points') return check
def run_simulation(world, parameters, timestep, n_iterations, logs): """Run simulation""" # Set parameters pylog.info( "Running new simulation:\n {}".format("\n ".join([ "{}: {}".format(key, value) for key, value in parameters.items() ])) ) # Setup salamander control salamander = SalamanderCMC( world, n_iterations, logs=logs, parameters=parameters ) # Simulation iteration = 0 while world.step(timestep) != -1: iteration += 1 if iteration >= n_iterations: break salamander.step(parameters) # Log data pylog.info("Logging simulation data to {}".format(logs)) salamander.log.save_data()
def s_theta_ref2(self, value): """ Keyword Arguments: value -- Set the value of spring 2 reference angle [rad] """ self.parameters['s_theta_ref2'] = value pylog.info( 'Changed spring 2 reference angle to {} [rad]'.format( self.parameters['s_theta_ref2']))
def __init__(self, **kwargs): super(PendulumParameters, self).__init__('Pendulum') self.parameters = {} self.units = {} self.units['g'] = 'N-m/s2' self.units['m'] = 'kg' self.units['L'] = 'm' self.units['I'] = 'kg-m**2' self.units['sin'] = '' self.units['PERTURBATION'] = 'bool' # Initialize parameters self.parameters = { 'g': 9.81, 'm': 1., 'L': 1., 'I': 0.0, 'sin': np.sin, 'PERTURBATION': False} # Pendulum parameters self.g = kwargs.pop("g", 9.81) # Gravity constant self.m = kwargs.pop("m", 1.) # Mass self.L = kwargs.pop("L", 1.) # Length self.sin = kwargs.pop("sin", np.sin) # Sine function self.PERTURBATION = kwargs.pop("PERTURBATION", False) # Perturbation pylog.info(self) return
def run_simulation(world, parameters, timestep, n_iterations, logs): """Run simulation""" # Set parameters pylog.info("Running new simulation:\n {}".format("\n ".join( ["{}: {}".format(key, value) for key, value in parameters.items()]))) # Setup salamander control salamander = SalamanderCMC(world, n_iterations, logs=logs, parameters=parameters) # Simulation #pos =[] iteration = 0 while world.step(timestep) != -1: iteration += 1 if iteration >= n_iterations: break salamander.step() #pos.append(salamander.position_sensors[1]) # plot_results.plot_positions(np.arange(0,n_iterations*timestep, timestep),pos) # Log data pylog.info("Logging simulation data to {}".format(logs)) salamander.log.save_data()
def exercise1d(time_param): """ Plots the v_ce-force relationship by running experiment with multiple weights.""" pylog.info("Exercise 1d") # Parameters load_min = 20 load_max = 300 nb_loads = 1000 load = np.linspace(load_min, load_max, num=nb_loads) muscle_stimulation = 1. # Experiment v_ce, tendon_force = isotonic_experiment( loads=load, muscle_stimulation=muscle_stimulation, time_param=time_param) # Plotting plt.figure('1_d_isotonic_load_var') plt.plot(v_ce, tendon_force) plt.title('Isotonic muscle experiment') plt.xlabel('Contractile element velocity [m/s]') plt.ylabel('Tendon force [N]') plt.axvline(x=0, color="k") plt.text(0.001, 750, "Equilibrium (v=0)", rotation=-90, color="k") plt.grid()
def find_ce_stretch_iso(muscle_sys, ce_stretch, time_param, stimulation=1, error_max=0.01): """Finds the total stretch [m] to apply to obtain a certain ce_stretch(relative) in isometric mode""" stretch = 0 # The stretch is constant for over compression (i.e[0,sth]) hence we wanna monitor this to avoid being # in a regime where the computations are biased. minimal_ce_stretch = None x0 = [0.0, muscle_sys.muscle.L_OPT] # Running experiments until we find a stretch that matches the conditions on CE while True: result = muscle_sys.integrate(x0=x0, time=time_param.times, time_step=time_param.t_step, stimulation=stimulation, muscle_length=stretch) if minimal_ce_stretch is None: minimal_ce_stretch = result.l_ce[ -1] # Monitoring the what the ce_stretch is in over compression else: if result.l_ce[-1] > ce_stretch * x0[1] and result.l_ce[ -1] > minimal_ce_stretch: pylog.info("Reaches l_ce stretch " + str(result.l_ce[-1] / muscle_sys.muscle.L_OPT) + " for total stretch of:" + str(stretch)) break else: stretch += error_max return stretch
def exercise1a(time_param): """ Runs and plot the length-force relationship for a muscle in isometric conditions.""" pylog.info("Part a") # Parameters muscle_stimulation = 1. ce_stretch_max = 1.5 ce_stretch_min = 0.5 nb_pts = 1000 handles = ["1_a_lce_vs_str", "1_a_lsl_vs_str", "1_a_lmtc_vs_str"] # Experiment active_force, passive_force, total_force, l_ce, l_slack, l_mtc = isometric_experiment( muscle_stimulation, ce_stretch_max, ce_stretch_min, nb_pts, time_param, ) # Plotting plot_isometric_data(active_force, passive_force, total_force, l_ce, l_slack, l_mtc, handle=handles)
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 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 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 evolution_dry(x0, time): """ Dry friction simulation """ pylog.info("Evolution with dry friction") parameters = PendulumParameters(d=0.03, dry=True) pylog.info(parameters) title = "{} with dry friction (x0={})" res = integrate(pendulum_system, x0, time, args=(parameters, )) res.plot_state(title.format("State", x0)) res.plot_phase(title.format("Phase", x0))
def evolution_perturbation(x0, time): """ Perturbation and no damping simulation """ pylog.info("Evolution with perturbations") parameters = PendulumParameters(d=0.0) pylog.info(parameters) title = "{} with perturbation (x0={})" res = integrate(pendulum_perturbation, x0, time, args=(parameters, )) res.plot_state(title.format("State", x0)) res.plot_phase(title.format("Phase", x0))
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 evolution_no_damping(x0, time): """ No damping simulation """ pylog.info("Evolution with no damping") parameters = PendulumParameters(d=0.0) pylog.info(parameters) title = "{} without damping (x0={})" res = integrate(pendulum_system, x0, time, args=(parameters, )) res.plot_state(title.format("State", x0)) res.plot_phase(title.format("Phase", x0))
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 pendulum_perturbation(state, time, *args): """ Function for system integration with perturbations. Setup your time based system pertubations within this function. The pertubation can either be applied to the states or as an external torque. """ pendulum = args[0] if time > 5 and time < 5.1: pylog.info("Applying state perturbation to pendulum_system") state[1] = 2. return pendulum.pendulum_system(state[0], state[1], time, torque=0.0)[:, 0]
def evolution_cases(time): """ Normal simulation """ pylog.info("Evolution with basic paramater") x0_cases = [["Normal", [0.1, 0]], ["Stable", [0.0, 0.0]], ["Unstable", [np.pi, 0.0]], ["Multiple loops", [0.1, 10.0]]] title = "{} case {} (x0={})" parameters = PendulumParameters() for name, x0 in x0_cases: res = integrate(pendulum_system, x0, time, args=(parameters, )) res.plot_state(title.format(name, "state", x0)) res.plot_phase(title.format(name, "phase", x0))
def run_simulation(world, parameters, timestep, n_iterations, logs): """Run simulation""" # Set parameters pylog.info("Running new simulation:\n {}".format("\n ".join( ["{}: {}".format(key, value) for key, value in parameters.items()]))) # Setup salamander control salamander = SalamanderCMC(world, n_iterations, logs=logs, parameters=parameters) switch = 1 switch_T = np.inf switched = False # Simulation iteration = 0 while world.step(timestep) != -1: iteration += 1 if iteration >= n_iterations: break """ if iteration == n_iterations//3: #salamander.network.parameters.turn = 0.1 #9d1 salamander.network.parameters.drive = -3 salamander.network.parameters.update(salamander.network.parameters.parameters) if salamander.gps.getValues()[0] > switch and switched == False: #used for 9f salamander.network.parameters.walk = False salamander.network.parameters.update(salamander.network.parameters.parameters) switch_T = iteration print(switch_T) switched = True if salamander.gps.getValues()[0] < switch and switched == True: salamander.network.parameters.walk = True salamander.network.parameters.turn = 0 salamander.network.parameters.update(salamander.network.parameters.parameters) swiched = True if iteration == switch_T + 600: print("turning") salamander.network.parameters.turn = -0.11 salamander.network.parameters.update(salamander.network.parameters.parameters) elif iteration == switch_T + 3500: print("straight") salamander.network.parameters.turn = 0 salamander.network.parameters.update(salamander.network.parameters.parameters) """ salamander.step() # Log data pylog.info("Logging simulation data to {}".format(logs)) salamander.log.save_data()
def __init__(self, **kwargs): super(PendulumParameters, self).__init__() self._mass = 1.0 # Internal parameter : Do NOT use it! self._length = 1.0 # Internal parameter : Do NOT use it! self.g = kwargs.pop("g", 9.81) # Gravity constant self.I = None # Inertia be set automatically when mass and length are set self.m = kwargs.pop("m", 1.) # Mass self.L = kwargs.pop("L", 1.) # Length self.d = kwargs.pop("d", 0.3) # damping self.sin = kwargs.pop("sin", np.sin) # Sine function self.dry = kwargs.pop("dry", False) # Use dry friction (True or False) pylog.info(self)
def plot_integration_methods(**kwargs): """ Plot integration methods results """ pylog.info("Plotting integration results") # Results analytical = kwargs.pop("analytical", None) euler = kwargs.pop("euler", None) ode = kwargs.pop("ode", None) ode_rk = kwargs.pop("ode_rk", None) euler_ts_small = kwargs.pop("euler_ts_small", None) # Figures fig_all = kwargs.pop("figure", "Integration methods".replace(" ", "_")) fig_ts = "Integration methods smaller ts".replace(" ", "_") fig_euler = "Euler integration".replace(" ", "_") d = "." # Time steps information et_val = kwargs.pop("euler_timestep", None) ets_val = kwargs.pop("euler_timestep_small", None) et = " (ts={})".format(et_val) if et_val is not None else "" ets = " (ts={})".format(ets_val) if ets_val is not None else "" # Analytical if analytical is not None: analytical.plot_state(figure=fig_euler, label="Analytical", marker=d) # Euler if euler is not None: euler.plot_state(figure=fig_euler, label="Euler" + et, marker=d) # ODE ls = " " ode_plot = False if ode is not None: if ode_plot is False: analytical.plot_state(figure=fig_all, label="Analytical", marker=d) euler.plot_state(figure=fig_all, label="Euler" + et, marker=d) ode_plot = True ode.plot_state(figure=fig_all, label="LSODA", linestyle=ls, marker="x") # ODE Runge-Kutta if ode_rk is not None: if ode_plot is False: analytical.plot_state(figure=fig_all, label="Analytical", marker=d) euler.plot_state(figure=fig_all, label="Euler" + et, marker=d) ode_rk.plot_state(figure=fig_all, label="RK", linestyle=ls, marker=d) # Euler with lower time step if euler_ts_small is not None: euler_ts_small.plot_state(figure=fig_ts, label="Euler" + ets) analytical.plot_state(figure=fig_ts, label="Analytical", marker=d)
def isotonic_experiment(muscle_stimulation, loads, time_param=TimeParameters()): # Muscle muscle_parameters = MuscleParameters() muscle = Muscle(muscle_parameters) # Initial conditions x0 = [0] * StatesIsotonic.NB_STATES.value x0[StatesIsotonic.STIMULATION.value] = 0. x0[StatesIsotonic.L_CE.value] = muscle.L_OPT x0[StatesIsotonic.LOAD_POS.value] = muscle.L_OPT + muscle.L_SLACK x0[StatesIsotonic.LOAD_SPEED.value] = 0. # Containers v_ce = [] tendon_force = [] # Integration pylog.info("Running the experiments (this might take a while)...") for load in loads: # New load definition mass_parameters = MassParameters() mass_parameters.mass = load mass = Mass(mass_parameters) # System definition sys = IsotonicMuscleSystem() sys.add_muscle(muscle) sys.add_mass(mass) result = sys.integrate(x0=x0, time=time_param.times, time_step=time_param.t_step, time_stabilize=time_param.t_stabilize, stimulation=muscle_stimulation, load=load) # Result processing if result.l_mtc[-1] > x0[StatesIsotonic.LOAD_POS.value]: # Extension index = result.v_ce.argmax() v_ce.append(result.v_ce.max()) tendon_force.append(result.tendon_force[index]) else: # Contraction index = result.v_ce.argmin() v_ce.append(result.v_ce.min()) tendon_force.append(result.tendon_force[index]) return v_ce, tendon_force