In [1]:
from controlboros import StateSpaceBuilder, RateWrapper
import matplotlib.pyplot as plt
import numpy as np
from scipy import signal
%matplotlib inline
%config InlineBackend.figure_format = 'retina'
In this notebook, we shall simulate the step response of a simple system using scipy.signal
and controlboros
.
The system is defined by the following transfer function:
$$H(s) = \frac{1}{s + 1}$$We want to simulate from 0 to 1 s:
In [2]:
t_begin, t_end = 0.0, 1.0
We use 1 ms sample time for the reference simulation performed with scipy.signal
:
In [3]:
dt = 1.0e-3
As for controlboros
, we shall discretise $H(s)$ with 0.1 ms sample rate but simulate it with 1 ms sample rate. We define the corresponding rate multiplier:
In [4]:
multiplier = 100
Ok. Now we create a reference system using scipy.signal
and compute its step response:
In [5]:
t_ref, y_ref = signal.step(
([1.0], [1.0, 1.0]),
T=np.arange(t_begin, t_end, dt),
)
Now we create a controlboros.StateSpace
model using the builder pattern and wrap it using controlboros.RateWrapper
:
In [6]:
sys_cb = StateSpaceBuilder().from_tf([1.0], [1.0, 1.0])\
.discretise(dt*multiplier)\
.build()
sys_cb_wrapped = RateWrapper(sys_cb, multiplier)
And we initialise arrays for the step response:
In [7]:
excitation = np.array([1.0]) # Constant step excitation
t_cb = np.arange(t_begin, t_end, dt)
y_cb = np.zeros((len(t_cb),))
We're ready to run the main loop:
In [8]:
# Reset the inital state of the systems,
# helpful if you run this cell multiple times!
sys_cb_wrapped.set_state_to_zero()
sys_cb_wrapped.reset_wrapper()
for i in range(len(t_cb)):
y_cb[i] = sys_cb_wrapped.push_stateful(excitation)
Plot and compare results:
In [9]:
plt.figure(figsize=(7, 5))
plt.plot(t_ref, y_ref)
plt.step(t_cb, y_cb, where="post")
plt.xlabel("Time (s)")
plt.ylabel("Output")
plt.legend(["scipy.signal", "controlboros"])
plt.grid()
plt.show()