Automatic Control Knowledge Repository

You currently have javascript disabled. Some features will be unavailable. Please consider enabling javascript.

Details for: "n integrator chain"

Name: n integrator chain (Key: CAS0M)
Path: ackrep_data/system_models/n_integrator_chain_system View on GitHub
Type: system_model
Short Description: a chain of n integrators
Created: 2022-04-21
Compatible Environment: default_conda_environment (Key: CDAMA)
Source Code [ / ] simulation.py
# -*- coding: utf-8 -*-
"""
Created on Mon Jun  7 19:06:37 2021

@author: Rocky
"""

import numpy as np
import system_model
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 plt
import os


def simulate():

    order = 5
    model_two = system_model.Model(order)

    u = model_two.uu_func

    """RHS-Function of the brockett_model
        Args:
            t (float, positive): time
            x (ndarray): state vector
        Returns:
            dx/dt (ndarray): time derivative of state vector at time t
    """

    def chain_integrator_model(t, xx_nv):

        dxx_dt_nv = xx_nv * 1
        dxx_dt_nv[:-1] = xx_nv[1:]
        dxx_dt_nv[-1] = u(t, xx_nv)

        return dxx_dt_nv

    xx0 = [0, 0, 0, 0, 0]

    model = system_model.Model(x_dim=len(xx0))

    rhs_xx_pp_symb = model.get_rhs_symbolic()
    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()

    t_end = 30
    tt = times = np.linspace(0, t_end, 1000)
    sim = solve_ivp(chain_integrator_model, (0, t_end), xx0, t_eval=tt)

    save_plot(sim)

    return sim


def save_plot(sim):

    plt.plot(sim.t, sim.y[0], label="x1", lw=1)
    plt.plot(sim.t, sim.y[1], label="x2", lw=1)
    plt.plot(sim.t, sim.y[2], label="x3", lw=1)
    plt.plot(sim.t, sim.y[3], label="x4", lw=1)
    plt.plot(sim.t, sim.y[4], label="x5", lw=1)

    plt.title("State progress")
    plt.xlabel("Time [s]")
    plt.ylabel("y")
    plt.legend()
    plt.grid()

    plt.tight_layout()

    save_plot_in_dir()


def evaluate_simulation(simulation_data):
    """

    :param simulation_data: simulation_data of system_model
    :return:
    """

    expected_final_state = [
        32337.334058261687,
        3092.752509636077,
        144.88833045860406,
        -1.4410336827947148,
        -0.0673030971647946,
    ]

    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 = 1

        # only needed for n extendable systems -- MODEL DEPENDENT
        self.default_param_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
        """
        T = 10
        y1 = 0
        # create symbolic polnomial function
        f1 = sp.sin(2 * sp.pi * self.t_symb / T)
        # create symbolic piecewise defined symbolic transition function
        transition = st.piece_wise((0, self.t_symb < 0), (f1, self.t_symb < T), (-f1, self.t_symb < 2 * T), (y1, True))
        # transform symbolic to numeric function
        transition_func = st.expr_to_func(self.t_symb, transition)

        # Wrapper function to unify function arguments
        def uu_rhs(t, xx_nv):
            """
            :param t:(vector) time
            :param xx_nv:(vector or array of vectors) numeric state vector
            :return:(vector) numeric inputs
            """
            res = transition_func(t)
            return res

        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

        dxx_dt_symb = self.xx_symb * 1
        dxx_dt_symb[:-1] = self.xx_symb[1:]
        dxx_dt_symb[-1] = self.uu_symb[0]

        self.dxx_dt_symb = sp.Matrix(dxx_dt_symb)

        return self.dxx_dt_symb
parameters.py
# This model does not need any parameters.

Related Problems:
Extensive Material:
Download pdf
Result: Success.
Last Build: Checkout CI Build
Runtime: 3.1 (estimated: 10s)
Plot:

The image of the latest CI job is not available. This is a fallback image.