simulation.py
# -*- coding: utf-8 -*-
"""
Created on Mon Jun 7 19:06:37 2021
@author: Rocky
"""
import numpy as np
import system_model as bi
from scipy.integrate import solve_ivp
from ackrep_core import ResultContainer
from ackrep_core.system_model_management import save_plot_in_dir
import matplotlib.pyplot as pyplot
import os
def simulate():
model = bi.Model()
rhs_xx_pp_symb = model.get_rhs_symbolic()
print("Simulation with input functions: u1 = sin(omega*t), u2 = cos(omega*t)\n")
print("Computational Equations:\n")
for i, eq in enumerate(rhs_xx_pp_symb):
print(f"dot_x{i+1} =", eq)
rhs = model.get_rhs_func()
xx0 = [0, 0, 0]
t_end = 10
tt = np.linspace(0, t_end, 1000) # vector of times for simulation
sim = solve_ivp(rhs, (0, t_end), xx0, t_eval=tt)
save_plot(sim)
return sim
def save_plot(sol):
pyplot.plot(sol.t, sol.y[0], label="$x_1$")
pyplot.plot(sol.t, sol.y[1], label="$x_2$")
pyplot.plot(sol.t, sol.y[2], label="$x_3$")
pyplot.title("State Progress")
pyplot.xlabel("Time [s]")
pyplot.legend()
pyplot.grid()
pyplot.tight_layout()
save_plot_in_dir()
def evaluate_simulation(simulation_data):
"""
:param simulation_data: simulation_data of system_model
:return:
"""
expected_final_state = [1.5126199035042642e-05, -1.6950186169609194e-05, 0.7956450415081588]
rc = ResultContainer(score=1.0)
simulated_final_state = simulation_data.y[:, -1]
rc.final_state_errors = [
simulated_final_state[i] - expected_final_state[i] for i in np.arange(0, len(simulated_final_state))
]
rc.success = np.allclose(expected_final_state, simulated_final_state, rtol=0, atol=1e-2)
return rc
system_model.py
# -*- coding: utf-8 -*-
"""
Created on Wed Jun 9 13:33:34 2021
@author: Jonathan Rockstroh
"""
import sympy as sp
import symbtools as st
import importlib
import sys, os
from ipydex import IPS, activate_ips_on_exception # for debugging only
from ackrep_core.system_model_management import GenericModel, import_parameters
# Import parameter_file
params = None
class Model(GenericModel):
def initialize(self):
"""
this function is called by the constructor of GenericModel
:return: None
"""
# Define number of inputs -- MODEL DEPENDENT
self.u_dim = 2
# Set "sys_dim" to constant value, if system dimension is constant
# else set "sys_dim" to x_dim -- MODEL DEPENDENT
self.sys_dim = 3
# check existance of params file -> if not: System is defined to hasn't
# parameters
self.has_params = True
self.params = params
# ----------- SET DEFAULT INPUT FUNCTION ---------- #
# --------------- Only for non-autonomous Systems
# --------------- MODEL DEPENDENT
def uu_default_func(self):
"""
:param t:(scalar or vector) Time
:param xx_nv: (vector or array of vectors) state vector with
numerical values at time t
:return:(function with 2 args - t, xx_nv) default input function
"""
def uu_rhs(t, xx_nv):
u1 = 0
u2 = 0
if t > 0:
u1 = sp.sin(4 * sp.pi * t)
u2 = sp.cos(4 * sp.pi * t)
return [u1, u2]
return uu_rhs
# ----------- SYMBOLIC RHS FUNCTION ---------- #
# --------------- MODEL DEPENDENT
def get_rhs_symbolic(self):
"""
:return:(matrix) symbolic rhs-functions
"""
if self.dxx_dt_symb is not None:
return self.dxx_dt_symb
x1, x2, x3 = self.xx_symb
# u0 = input force
u1, u2 = self.uu_symb
# create symbolic rhs functions
dx1_dt = u1
dx2_dt = u2
dx3_dt = x2 * u1 - x1 * u2
# put rhs functions into a vector
self.dxx_dt_symb = sp.Matrix([dx1_dt, dx2_dt, dx3_dt])
return self.dxx_dt_symb
parameters.py
# This model does not need any parameters.