Esempio n. 1
0
def run_demo(with_plots=True):
    """This example demonstrates how the Python interface to the three
    different ASTs in the compiler can be used. The JPype package is
    used to create Java objects in a Java Virtual Machine which is
    seamlessly integrated with the Python shell. The Java objects can
    be accessed interactively and methods of the object can be
    invoked.

    For more information about the Java classes and their methods used
    in this example, please consult the API documentation for the
    Modelica compiler, <a href=http://www.jmodelica.org/page/22>. Notice
    however that the documentation for the compiler front-ends is
    still very rudimentary. Also, the interfaces to the source and
    instance AST will be made more user friendly in upcoming versions.

    Three different usages of ASTs are shown:

    1. Count the number of classes in the Modelica standard
    library. In this example, a Python function is defined to traverse
    the source AST which results from parsing of the Modelica standard
    library.

    2. Instantiate the CauerLowPassAnalog model. The instance AST for
    this model is dumped and it is demonstrated how the merged
    modification environments can be accessed.

    3. Flatten the CauerLowPassAnalog model instance and print some
    statistics of the flattened Model.
    """

    curr_dir = os.path.dirname(os.path.abspath(__file__))

    # Create a compiler
    mc = ModelicaCompiler()

    # Don't parse the file if it har already been parsed.
    try:
        source_root.getProgramRoot()
    except:
        # Parse the file CauerLowPassAnalog.mo and get the root node
        # of the source AST
        source_root = mc.parse_model(curr_dir + "/files/CauerLowPassAnalog.mo")

    # Don't load the standard library if it is already loaded
    try:
        modelica.getName().getID()
    except NameError, e:
        # Load the Modelica standard library and get the class
        # declaration AST node corresponding to the Modelica
        # package.
        modelica = source_root.getProgram().getLibNode(1). \
                   getStoredDefinition().getElement(0)
Esempio n. 2
0
def run_demo(with_plots=True):
    """
    An example on how to simulate a model using the DAE simulator. The
    result can be compared with that of sim_rlc.py which has solved the
    same problem using dymola. Also writes information to a file.
    """

    curr_dir = os.path.dirname(os.path.abspath(__file__));

    model_name = 'RLC_Circuit'
    mofile = curr_dir+'/files/RLC_Circuit.mo'
    
    
    mc = ModelicaCompiler()
    
    # Comile the Modelica model first to C code and
    # then to a dynamic library
    mc.compile_model(mofile,model_name,target='ipopt')

    # Load the dynamic library and XML data
    model=jmi.Model(model_name)

    # Create DAE initialization object.
    init_nlp = NLPInitialization(model)
    
    # Create an Ipopt solver object for the DAE initialization system
    init_nlp_ipopt = InitializationOptimizer(init_nlp)
        
    # Solve the DAE initialization system with Ipopt
    init_nlp_ipopt.init_opt_ipopt_solve()

    simulator = SundialsDAESimulator(model, verbosity=3, start_time=0.0, final_time=30.0, time_step=0.01)
    simulator.run()
        
    simulator.write_data()

    # Load the file we just wrote to file
    res = jmodelica.io.ResultDymolaTextual('RLC_Circuit_result.txt')
    sine_y = res.get_variable_data('sine.y')
    resistor_v = res.get_variable_data('resistor.v')
    inductor1_i = res.get_variable_data('inductor1.i')

    assert N.abs(resistor_v.x[-1] - 0.159255008028) < 1e-3, \
           "Wrong value in simulation result in RLC.py"
    
    #Ts, ys = simulator.get_solution('sine.y','resistor.v','inductor1.i')
    fig = p.figure()
    p.plot(sine_y.t, sine_y.x, resistor_v.t, resistor_v.x, inductor1_i.t, inductor1_i.x)
    p.legend(('sine.y','resistor.v','inductor1.i'))
    p.show()
Esempio n. 3
0
def run_demo(with_plots=True):

    mc = ModelicaCompiler()

    # Comile the Modelica model first to C code and
    # then to a dynamic library
    mofile = 'RLC_Circuit.mo'
    optpackage = 'RLC_Circuit'
    path = get_example_path()
    os.chdir(path)

    mc.compile_model(os.path.join(path, mofile),
                     optpackage,
                     target='ipopt')

    # Load the dynamic library and XML data
    rlc=jmi.Model('RLC_Circuit')


    # Create DAE initialization object.
    init_rlc = NLPInitialization(rlc)
        
    # Create an Ipopt solver object for the DAE initialization system
    init_rlc_ipopt = InitializationOptimizer(init_rlc)

    # Solve the DAE initialization system with Ipopt
    init_rlc_ipopt.init_opt_ipopt_solve()

    # Simulate system...

    # Verify solution by loading result file generated by dymola
    res = jmodelica.io.ResultDymolaBinary('RLC_Circuit_dymola.mat')

    # Get result variables
    V_in = res.get_variable_data('sine.y')
    V_resistor = res.get_variable_data('resistor.v')
    I_inductor1 = res.get_variable_data('inductor1.i')

    if with_plots:
        plt.figure(1)
        plt.clf()
        plt.hold(True)
        plt.plot(V_in.t,V_in.x)
        plt.plot(V_resistor.t,V_resistor.x)
        plt.plot(I_inductor1.t,I_inductor1.x)
        plt.show()
Esempio n. 4
0
    def test_state_start_values_fixed(self):
        """ Test of the compiler option state_start_values_fixed
        """
        """ Test of the dae_get_sizes in Model
        """

        model = os.path.join("files", "VDP_pack.mo")
        fpath = os.path.join(path_to_tests, model)
        cpath = "VDP_pack.VDP"
        fname = cpath.replace('.', '_', 1)

        mc = ModelicaCompiler()

        mc.set_boolean_option('state_start_values_fixed', False)

        mc.compile_model(fpath, cpath)

        # Load the dynamic library and XML data
        vdp = jmi.Model(fname)

        res_n_eq_F = 2
        n_eq_F, n_eq_R = vdp.jmimodel.dae_get_sizes()
        assert n_eq_F==res_n_eq_F, \
               "test_jmi.py: test_Model_dae_get_sizes: Wrong number of DAE equations."

        res_n_eq_F0 = 2
        res_n_eq_F1 = 5
        res_n_eq_Fp = 0
        res_n_eq_R0 = 0
        n_eq_F0, n_eq_F1, n_eq_Fp, n_eq_R0 = vdp.jmimodel.init_get_sizes()
        assert n_eq_F0==res_n_eq_F0 and n_eq_F1==res_n_eq_F1 and n_eq_Fp==res_n_eq_Fp and n_eq_R0==res_n_eq_R0, \
               "test_jmi.py: test_Model_dae_get_sizes: Wrong number of DAE initialization equations."
Esempio n. 5
0
def run_demo(with_plots=True):
    """ Load change of a distillation column. The distillation column model
    is documented in the paper:

    @Article{hahn+02,
    title={An improved method for nonlinear model reduction using balancing of empirical gramians},
    author={Hahn, J. and Edgar, T.F.},
    journal={Computers and Chemical Engineering},
    volume={26},
    number={10},
    pages={1379-1397},
    year={2002}
    }
    """

    curr_dir = os.path.dirname(os.path.abspath(__file__))

    # Create a Modelica compiler instance
    mc = ModelicaCompiler()

    # Compile the stationary initialization model into a DLL
    mc.compile_model(curr_dir + "/files/DISTLib.mo",
                     "DISTLib.Binary_Dist_initial",
                     target='ipopt')

    # Load a model instance into Python
    init_model = jmi.Model("DISTLib_Binary_Dist_initial")

    # Create DAE initialization object.
    init_nlp = NLPInitialization(init_model)

    # Create an Ipopt solver object for the DAE initialization system
    init_nlp_ipopt = InitializationOptimizer(init_nlp)

    # Set inputs for Stationary point A
    u1_0_A = 3.0
    init_model.set_value('u1', u1_0_A)

    # init_nlp_ipopt.init_opt_ipopt_set_string_option("derivative_test","first-order")
    #init_nlp_ipopt.init_opt_ipopt_set_int_option("max_iter",5)

    # Solve the DAE initialization system with Ipopt
    init_nlp_ipopt.init_opt_ipopt_solve()

    # Store stationary point A
    y_A = N.zeros(32)
    x_A = N.zeros(32)
    # print(' *** Stationary point A ***')
    print '(Tray index, x_i_A, y_i_A)'
    for i in range(N.size(y_A)):
        y_A[i] = init_model.get_value('y' + str(i + 1))
        x_A[i] = init_model.get_value('x' + str(i + 1))
        print '(' + str(i + 1) + ', %f, %f)' % (x_A[i], y_A[i])

    # Set inputs for stationary point B
    u1_0_B = 3.0 - 1
    init_model.set_value('u1', u1_0_B)

    # init_nlp_ipopt.init_opt_ipopt_set_string_option("derivative_test","first-order")
    #init_nlp_ipopt.init_opt_ipopt_set_int_option("max_iter",5)

    # Solve the DAE initialization system with Ipopt
    init_nlp_ipopt.init_opt_ipopt_solve()

    # Store stationary point B
    y_B = N.zeros(32)
    x_B = N.zeros(32)
    # print(' *** Stationary point B ***')
    print '(Tray index, x_i_B, y_i_B)'
    for i in range(N.size(y_B)):
        y_B[i] = init_model.get_value('y' + str(i + 1))
        x_B[i] = init_model.get_value('x' + str(i + 1))
        print '(' + str(i + 1) + ', %f, %f)' % (x_B[i], y_B[i])

    # ## Set up and solve an optimal control problem.

    # Create an OptimicaCompiler instance
    oc = OptimicaCompiler()

    # Generate initial equations for states even if fixed=false
    oc.set_boolean_option('state_start_values_fixed', True)

    # Compil the Model
    oc.compile_model(
        (curr_dir + "/files/DISTLib.mo", curr_dir + "/files/DISTLib_Opt.mo"),
        "DISTLib_Opt.Binary_Dist_Opt1",
        target='ipopt')

    # Load the dynamic library and XML data
    model = jmi.Model("DISTLib_Opt_Binary_Dist_Opt1")

    # Initialize the model with parameters

    # Initialize the model to stationary point A
    for i in range(N.size(x_A)):
        model.set_value('x' + str(i + 1) + '_0', x_A[i])

    # Set the target values to stationary point B
    model.set_value('u1_ref', u1_0_B)
    model.set_value('y1_ref', y_B[0])

    # Initialize the optimization mesh
    n_e = 50  # Number of elements
    hs = N.ones(n_e) * 1. / n_e  # Equidistant points
    n_cp = 3
    # Number of collocation points in each element

    # Create an NLP object representing the discretized problem
    nlp = ipopt.NLPCollocationLagrangePolynomials(model, n_e, hs, n_cp)

    # Create an Ipopt NLP object
    nlp_ipopt = ipopt.CollocationOptimizer(nlp)

    #nlp_ipopt.opt_sim_ipopt_set_string_option("derivative_test","first-order")

    # If the convergence is slow, may increase tolerance.
    #nlp_ipopt.opt_sim_ipopt_set_num_option("tol",0.0001)

    #Solve the optimization problem
    nlp_ipopt.opt_sim_ipopt_solve()

    # Write to file. The resulting file  can be
    # loaded into Dymola.
    nlp.export_result_dymola()

    # Load the file we just wrote
    res = jmodelica.io.ResultDymolaTextual(
        'DISTLib_Opt_Binary_Dist_Opt1_result.txt')

    # Extract variable profiles
    u1_res = res.get_variable_data('u1')
    u1_ref_res = res.get_variable_data('u1_ref')
    y1_ref_res = res.get_variable_data('y1_ref')

    x_res = []
    x_ref_res = []
    for i in range(N.size(x_B)):
        x_res.append(res.get_variable_data('x' + str(i + 1)))

    y_res = []
    for i in range(N.size(x_B)):
        y_res.append(res.get_variable_data('y' + str(i + 1)))

    # Plot the results
    if with_plots:
        plt.figure(1)
        plt.clf()
        plt.hold(True)
        plt.subplot(311)
        plt.title('Liquid composition')
        plt.plot(x_res[0].t, x_res[0].x)
        plt.ylabel('x1')
        plt.grid()
        plt.subplot(312)
        plt.plot(x_res[16].t, x_res[16].x)
        plt.ylabel('x17')
        plt.grid()
        plt.subplot(313)
        plt.plot(x_res[31].t, x_res[31].x)
        plt.ylabel('x32')
        plt.grid()
        plt.xlabel('t [s]')
        plt.show()

        # Plot the results
        plt.figure(2)
        plt.clf()
        plt.hold(True)
        plt.subplot(311)
        plt.title('Vapor composition')
        plt.plot(y_res[0].t, y_res[0].x)
        plt.plot(y1_ref_res.t, y1_ref_res.x, '--')
        plt.ylabel('y1')
        plt.grid()
        plt.subplot(312)
        plt.plot(y_res[16].t, y_res[16].x)
        plt.ylabel('y17')
        plt.grid()
        plt.subplot(313)
        plt.plot(y_res[31].t, y_res[31].x)
        plt.ylabel('y32')
        plt.grid()
        plt.xlabel('t [s]')
        plt.show()

        plt.figure(3)
        plt.clf()
        plt.hold(True)
        plt.plot(u1_res.t, u1_res.x)
        plt.ylabel('u')
        plt.plot(u1_ref_res.t, u1_ref_res.x, '--')
        plt.xlabel('t [s]')
        plt.title('Reflux ratio')
        plt.grid()
        plt.show()
Esempio n. 6
0
from jmodelica.compiler import ModelicaCompiler
from jmodelica.compiler import OptimicaCompiler
import jmodelica as jm

jm_home = jm.environ['JMODELICA_HOME']
path_to_examples = os.path.join('Python', 'jmodelica', 'examples')

model_mc = os.path.join('files', 'Pendulum_pack_no_opt.mo')
fpath_mc = os.path.join(jm_home, path_to_examples, model_mc)
cpath_mc = "Pendulum_pack.Pendulum"

model_oc = os.path.join('files', 'Pendulum_pack.mo')
fpath_oc = os.path.join(jm_home, path_to_examples, model_oc)
cpath_oc = "Pendulum_pack.Pendulum_Opt"

mc = ModelicaCompiler()
ModelicaCompiler.set_log_level(ModelicaCompiler.LOG_ERROR)
mc.set_boolean_option('state_start_values_fixed', True)

oc = OptimicaCompiler()
OptimicaCompiler.set_log_level(OptimicaCompiler.LOG_ERROR)
oc.set_boolean_option('state_start_values_fixed', True)


@testattr(stddist=True)
def test_compile():
    """
    Test that compilation is possible with compiler 
    and that all obligatory files are created. 
    """
Esempio n. 7
0
import nose

from jmodelica.simulation.sundials import SundialsODESimulator
from jmodelica.simulation.sundials import SundialsDAESimulator
from jmodelica.tests import testattr
import jmodelica.simulation.sundials as sundials
import jmodelica.simulation
import jmodelica.jmi as jmi
from jmodelica.compiler import ModelicaCompiler
from jmodelica.compiler import OptimicaCompiler

jm_home = os.environ.get('JMODELICA_HOME')
path_to_examples = os.path.join(jm_home, "Python", "jmodelica", "examples")
path_to_tests = os.path.join(jm_home, "Python", "jmodelica", "tests")

mc = ModelicaCompiler()
oc = OptimicaCompiler()
oc.set_boolean_option('state_start_values_fixed', True)
sep = os.path.sep


class TestSundialsDAESimulator:
    @classmethod
    def setUpClass(cls):
        """Compile the test model. (This is only run once during the test)"""
        modelf = "files" + sep + "Pendulum_pack_no_opt.mo"
        fpath = os.path.join(path_to_examples, modelf)
        cpath = "Pendulum_pack.Pendulum"
        fname = cpath.replace('.', '_', 1)

        mc.compile_model(fpath, cpath)
Esempio n. 8
0
#
# 2. An optimal control problem is solved where the objective
#    Is to transfer the state of the system from stationary
#    point A to point B. Here, it is also demonstrated how
#    to set parameter values in a model. More information
#    about the simultaneous optimization algorithm can be
#    found at http://www.jmodelica.org/page/10.
#
# 3. The optimization result is saved to file and then
#    the important variables are plotted.
#

curr_dir = os.path.dirname(os.path.abspath(__file__))

# Create a Modelica compiler instance
mc = ModelicaCompiler()

# Don't generate initial equations for states if fixed=false
mc.set_boolean_option('state_start_values_fixed', False)

# Compile the stationary initialization model into a DLL
mc.compile_model(curr_dir + "/files/CSTRLib.mo",
                 "CSTRLib.Components.Two_CSTRs_stat_init",
                 target='ipopt')
#mc.compile_dll("CSTRLib_Components_Two_CSTRs_stat_init",target='ipopt')

# Load a model instance into Python
init_model = jmi.Model("CSTRLib_Components_Two_CSTRs_stat_init")

# Create DAE initialization object.
init_nlp = jmi.DAEInitializationOpt(init_model)
Esempio n. 9
0
def run_demo(with_plots=True):
    """This example is based on a system composed of two
    Continously Stirred Tank Reactors (CSTRs) in series.
    The example demonstrates the following steps:
    
    1. How to solve a DAE initialization problem. The initialization
       model have equations specifying that all derivatives
       should be identically zero, which implies that a
       stationary solution is obtained. Two stationary points,
       corresponding to different inputs, are computed. We call
       the stationary points A and B respectively. For more information
       about the DAE initialization algorithm, see
       http://www.jmodelica.org/page/10.
    
    2. An optimal control problem is solved where the objective
       Is to transfer the state of the system from stationary
       point A to point B. Here, it is also demonstrated how
       to set parameter values in a model. More information
       about the simultaneous optimization algorithm can be
       found at http://www.jmodelica.org/page/10.
    
    3. The optimization result is saved to file and then
       the important variables are plotted."""

    curr_dir = os.path.dirname(os.path.abspath(__file__))

    # Create a Modelica compiler instance
    mc = ModelicaCompiler()

    # Compile the stationary initialization model into a DLL
    mc.compile_model(curr_dir + "/files/CSTRLib.mo",
                     "CSTRLib.Components.Two_CSTRs_stat_init",
                     target='ipopt')

    # Load a model instance into Python
    init_model = jmi.Model("CSTRLib_Components_Two_CSTRs_stat_init")

    # Create DAE initialization object.
    init_nlp = NLPInitialization(init_model)

    # Create an Ipopt solver object for the DAE initialization system
    init_nlp_ipopt = InitializationOptimizer(init_nlp)

    # Set inputs for Stationary point A
    u1_0_A = 1
    u2_0_A = 1
    init_model.set_value('u1', u1_0_A)
    init_model.set_value('u2', u2_0_A)

    # init_nlp_ipopt.init_opt_ipopt_set_string_option("derivative_test","first-order")
    #init_nlp_ipopt.init_opt_ipopt_set_int_option("max_iter",5)

    # Solve the DAE initialization system with Ipopt
    init_nlp_ipopt.init_opt_ipopt_solve()

    # Store stationary point A
    CA1_0_A = init_model.get_value('CA1')
    CA2_0_A = init_model.get_value('CA2')
    T1_0_A = init_model.get_value('T1')
    T2_0_A = init_model.get_value('T2')

    # Print some data for stationary point A
    print(' *** Stationary point A ***')
    print('u = [%f,%f]' % (u1_0_A, u2_0_A))
    print('CAi = [%f,%f]' % (CA1_0_A, CA2_0_A))
    print('Ti = [%f,%f]' % (T1_0_A, T2_0_A))

    # Set inputs for stationary point B
    u1_0_B = 1.1
    u2_0_B = 0.9
    init_model.set_value('u1', u1_0_B)
    init_model.set_value('u2', u2_0_B)

    # init_nlp_ipopt.init_opt_ipopt_set_string_option("derivative_test","first-order")
    #init_nlp_ipopt.init_opt_ipopt_set_int_option("max_iter",5)

    # Solve the DAE initialization system with Ipopt
    init_nlp_ipopt.init_opt_ipopt_solve()

    # Stationary point B
    CA1_0_B = init_model.get_value('CA1')
    CA2_0_B = init_model.get_value('CA2')
    T1_0_B = init_model.get_value('T1')
    T2_0_B = init_model.get_value('T2')

    # Print some data for stationary point B
    print(' *** Stationary point B ***')
    print('u = [%f,%f]' % (u1_0_B, u2_0_B))
    print('CAi = [%f,%f]' % (CA1_0_B, CA2_0_B))
    print('Ti = [%f,%f]' % (T1_0_B, T2_0_B))

    ## Set up and solve an optimal control problem.

    # Create an OptimicaCompiler instance
    oc = OptimicaCompiler()

    # Compil the Model
    oc.compile_model(
        (curr_dir + "/files/CSTRLib.mo", curr_dir + "/files/CSTR2_Opt.mo"),
        "CSTR2_Opt",
        target='ipopt')

    # Load the dynamic library and XML data
    model = jmi.Model("CSTR2_Opt")

    # Initialize the model with parameters

    # Initialize the model to stationary point A
    model.set_value('two_CSTRs_Series.CA1_0', CA1_0_A)
    model.set_value('two_CSTRs_Series.CA2_0', CA2_0_A)
    model.set_value('two_CSTRs_Series.T1_0', T1_0_A)
    model.set_value('two_CSTRs_Series.T2_0', T2_0_A)

    # Set the target values to stationary point B
    model.set_value('u1_ref', u1_0_B)
    model.set_value('u2_ref', u2_0_B)
    model.set_value('CA1_ref', CA1_0_B)
    model.set_value('CA2_ref', CA2_0_B)

    # Initialize the optimization mesh
    n_e = 30  # Number of elements
    hs = N.ones(n_e) * 1. / n_e  # Equidistant points
    n_cp = 3
    # Number of collocation points in each element

    # Create an NLP object representing the discretized problem
    nlp = ipopt.NLPCollocationLagrangePolynomials(model, n_e, hs, n_cp)

    # Create an Ipopt NLP object
    nlp_ipopt = ipopt.CollocationOptimizer(nlp)

    #nlp_ipopt.opt_sim_ipopt_set_string_option("derivative_test","first-order")

    # The convergence is slow, for some reason, increasing tolerance.
    nlp_ipopt.opt_sim_ipopt_set_num_option("tol", 0.0001)

    #Solve the optimization problem
    nlp_ipopt.opt_sim_ipopt_solve()

    # Write to file. The resulting file (CSTR2_Opt_result.txt) can be
    # loaded into Dymola.
    nlp.export_result_dymola()

    # Load the file we just wrote
    res = jmodelica.io.ResultDymolaTextual('CSTR2_Opt_result.txt')

    # Extract variable profiles
    CA1_res = res.get_variable_data('two_CSTRs_Series.CA1')
    CA2_res = res.get_variable_data('two_CSTRs_Series.CA2')
    T1_res = res.get_variable_data('two_CSTRs_Series.T1')
    T2_res = res.get_variable_data('two_CSTRs_Series.T2')
    u1_res = res.get_variable_data('two_CSTRs_Series.u1')
    u2_res = res.get_variable_data('two_CSTRs_Series.u2')

    CA1_ref_res = res.get_variable_data('CA1_ref')
    CA2_ref_res = res.get_variable_data('CA2_ref')

    u1_ref_res = res.get_variable_data('u1_ref')
    u2_ref_res = res.get_variable_data('u2_ref')

    # Plot the results
    if with_plots:
        plt.figure(1)
        plt.clf()
        plt.hold(True)
        plt.subplot(211)
        plt.plot(CA1_res.t, CA1_res.x)
        plt.plot(CA1_ref_res.t, CA1_ref_res.x, '--')
        plt.ylabel('Concentration reactor 1 [J/l]')
        plt.grid()
        plt.subplot(212)
        plt.plot(CA2_res.t, CA2_res.x)
        plt.plot(CA2_ref_res.t, CA2_ref_res.x, '--')
        plt.ylabel('Concentration reactor 2 [J/l]')
        plt.xlabel('t [s]')
        plt.grid()
        plt.show()

        plt.figure(2)
        plt.clf()
        plt.hold(True)
        plt.subplot(211)
        plt.plot(T1_res.t, T1_res.x)
        plt.ylabel('Temperature reactor 1 [K]')
        plt.grid()
        plt.subplot(212)
        plt.plot(T2_res.t, T2_res.x)
        plt.ylabel('Temperature reactor 2 [K]')
        plt.grid()
        plt.xlabel('t [s]')
        plt.show()

        plt.figure(3)
        plt.clf()
        plt.hold(True)
        plt.subplot(211)
        plt.plot(u1_res.t, u1_res.x)
        plt.ylabel('Input 1')
        plt.plot(u1_ref_res.t, u1_ref_res.x, '--')
        plt.grid()
        plt.subplot(212)
        plt.plot(u2_res.t, u2_res.x)
        plt.ylabel('Input 2')
        plt.plot(u2_ref_res.t, u2_ref_res.x, '--')
        plt.xlabel('t [s]')
        plt.grid()
        plt.show()