<jupyter_start><jupyter_text>Sustavi prvog reda bez nula UvodSustavi prvog reda bez nula su karakterizirani sljedećom prijenosnom funkcijom:\begin{equation}    G(s)=\frac{k}{s+k}.\end{equation}Vrijednost $k$ je važna jer definira sljdeće parametre:- $1/k$ označava *vremensku konstantu* odziva, koja definira vrijeme potrebno da step-odziv dosegne $\approx$ 63% svoje konačne vrijednosti.- $t_r$ označava *vrijeme porasta*, tj. vrijeme potrebno da odziv sustava poraste s 10\% na 90\% stacionarne vrijednosti.- $t_s$ označava *vrijeme smirivanja*, tj. vrijeme potrebno da odziv sustava posljednji put bude izvan opsega pogreške  (npr. 2\% kako je postavljeno u primjeru dolje).Step-odziv ovih sustava izražava se kao:\begin{equation}    c(t)=1-e^{-at},\end{equation}gdje je prisilni odziv sustava jednak $1$, a prirodni odziv $-e^{-at}$.--- Kako koristiti ovaj interaktivni primjer?Pomičite klizač za definiranje vrijednosti $k$ u prijenosnoj funkciji sustava prvog reda - $G(s)=\frac{k}{s+k}$ i promatrajte vremenski odziv tako definiranog sustava.<jupyter_code># set up plot
fig, ax = plt.subplots(figsize=[9.8,4],num='Sustav prvog reda')
ax.set_ylim([-1, 2])
ax.set_xlim([0, 5])
ax.grid(True)
ax.set_title ('Vremenski odziv')
ax.set_xlabel('$t$ [s]')
ax.set_ylabel('ulaz, izlaz')
xaxis = ax.axhline(y=0,color='k',lw=1)

response, = ax.plot([], [])
slope, = ax.plot([], [])
x1a, = ax.plot([], [])
y1a, = ax.plot([], [])
tr11, = ax.plot([], [])
trv1, = ax.plot([], [])
trv2, = ax.plot([], [])
trh1, = ax.plot([], [])
trh2, = ax.plot([], [])
ts11, = ax.plot([], [])
ts1, = ax.plot([], [])
ts2, = ax.plot([], [])
texttr=ax.text(0,0,'')
textts=ax.text(0,0,'')

ax.step([0,5],[0,1],color='C0',label='ulaz')

# generate x values
t = np.linspace(0, 2 * np.pi, 10000)
  
def response_func(t, k):
    """"Return response function"""
    return 1-np.exp(-k*t)

@widgets.interact(k=(1, 5, 1))


def update(k=1):
    """Remove old lines from plot and plot new one"""
    global response,slope,x1a,y1a,tr11,trv1,trv2,trh1,trh2,ts11,ts1,ts2,texttr,textts
    ax.lines.remove(response)
    ax.lines.remove(slope)
    ax.lines.remove(x1a)
    ax.lines.remove(y1a)
    ax.lines.remove(tr11)
    ax.lines.remove(trv1)
    ax.lines.remove(trv2)
    ax.lines.remove(trh1)
    ax.lines.remove(trh2)
    ax.lines.remove(ts11)
    ax.lines.remove(ts1)
    ax.lines.remove(ts2)
    texttr.remove()
    textts.remove()
    response, = ax.plot(t, response_func(t,k), color='C1',lw=2)
    response.set_label('izlaz')
    slope, = ax.plot([0,1/k], [0,1], color='C2',lw=2)
    slope.set_label('inicijalni nagib')
    x1a, = ax.plot([1/k,1/k],[0,1-np.exp(-1)],'--',color='k',lw=.8)
    y1a, = ax.plot([0,1/k],[1-np.exp(-1),1-np.exp(-1)],'--',color='k',lw=.8)
# rise time
    tr11, = ax.plot([-np.log(0.9)/k,-np.log(0.1)/k],[-0.5,-0.5],color='k',lw=.8)
    trv1, = ax.plot([-np.log(0.9)/k,-np.log(0.9)/k],[-0.5,0.1],'--',color='k',lw=.8)
    trv2, = ax.plot([-np.log(0.1)/k,-np.log(0.1)/k],[-0.5,0.9],'--',color='k',lw=.8)
    trh1, = ax.plot([0,-np.log(0.9)/k],[0.1,0.1],'--',color='k',lw=.8)
    trh2, = ax.plot([0,-np.log(0.1)/k],[0.9,0.9],'--',color='k',lw=.8)
# settling time
    ts11, = ax.plot([0,-np.log(0.02)/k],[-0.7,-0.7],color='k',lw=.8)
    ts1, = ax.plot([0,0],[-0.7,0],'--',color='k',lw=.8)
    ts2, = ax.plot([-np.log(0.02)/k,-np.log(0.02)/k],[-0.7,0.98],'--',color='k',lw=.8)
    ax.legend()
    texttr=ax.text((-np.log(0.1)/k-(-np.log(0.9)/k))/2,-0.45, '$t_r$',fontsize=13)
    textts=ax.text((-np.log(0.02)/k)/2-0.1,-0.65, '$t_s$',fontsize=13)

    plt.xticks([0,1/k,2,4], [0,'${1}/{%s}$'%k,2,4],fontsize=8)
    plt.yticks([0.1,0.5,0.63,0.9,1,1.5,2], [0.1,0.5,0.63,0.9,1,1.5,2],fontsize=8)
    
    num1=[k]
    den1=[1,k]
    display(Markdown('Prijenosna funkcija sustava $G(s)$ je jednaka:'))
    tf_sys1=c.TransferFunction(num1,den1)
    s=sym.Symbol('s')
    eq=(k/(s+k))
    display(eq)<jupyter_output><empty_output><jupyter_text>Sustavi drugog reda UvodZa razliku od gore predstavljenih sustava prvog reda, u kojima parametar $k$ utječe isključivo na brzinu odziva, promjene odgovarajućih parametara u sustavima drugog reda mogu utjecati na stvarni oblik odziva. Sljedeća su četiri odziva moguća kod ovih sustava:- *pretjerano prigušeni* odziv,- *nedovoljno prigušeni* odziv,- *neprigušeni* odziv, i- *kritično prigušeni* odziv. Kako koristiti ovaj interaktivni primjer?Pomičite klizače za definiranje vrijednosti $a$ i $b$ u prijenosnoj funkciji sustava drugog reda oblika $G(s)=\frac{b}{s^2+as+b}$ te promatrajte dijagram polova i nula, kao i vremenski odziv definiranog sustava.<jupyter_code># set up plot
fig1, ax1 = plt.subplots(1,2,figsize=[9.8,4],num='Sustav drugog reda')
ax1[0].set_ylim([-3.5, 3])
ax1[1].set_ylim([0, 2.5])
# ax1.set_xlim([0, 5])
ax1[0].grid(True)
ax1[1].grid(True)
ax1[0].axhline(y=0,color='k',lw=.8)
ax1[1].axhline(y=0,color='k',lw=.8)
ax1[0].axvline(x=0,color='k',lw=.8)
ax1[1].axvline(x=0,color='k',lw=.8)
ax1[0].set_xlabel('Re')
ax1[0].set_ylabel('Im')
ax1[1].set_xlabel('$t$ [s]')
ax1[1].set_ylabel('ulaz, izlaz')
ax1[0].set_title('Dijagram polova i nula')
ax1[1].set_title('Vremenski odziv')

t = np.linspace(0, 20, 10000)

textGs = ax1[0].text(0,0,'')

ax1[1].step([0,20],[0,1],color='C0',label='ulaz')

plotzero, = ax1[0].plot([], [])
response2, = ax1[1].plot([], [])

def response_func2(t, a, b):
    num_sys=np.array([b])
    den_sys=np.array([1,a,b])
    tf_sys=c.TransferFunction(num_sys,den_sys)
    poles_sys,zeros_sys=c.pzmap(tf_sys, Plot=False)
    T, yout = c.step_response(tf_sys,t)
    return T, yout, poles_sys, tf_sys
 
@widgets.interact(a=(0, 10, 1),b=(1,10,1))

def update(a=7,b=9):
    """ Update plots """
    global response2, plotzero, textGs
    ax1[0].lines.remove(plotzero)
    ax1[1].lines.remove(response2)
#     textGs.remove()
    T, yout, poles_sys, tf_sys = response_func2(t, a, b)
    plotzero, = ax1[0].plot(np.real(poles_sys), np.imag(poles_sys), 'xg', markersize=10, label = 'Polovi')
#     textGs = ax1[0].text(-7,1,tf_sys)
    response2, = ax1[1].plot(T,yout,color='C1',label='izlaz')
    s=sym.Symbol('s')
    eq=b/(s**2+a*s+b)
    coeff = [1,a,b]
    rootsdenom=np.roots(coeff)
    eq2=b/((s-rootsdenom[0])*(s-rootsdenom[1]))
    display(Markdown('Prijenosna funkcija sustava $G(s)$ je jednaka:'))
    display(eq),display(Markdown('ili')),display(eq2)

    if np.imag(poles_sys)[0] == 0 and np.imag(poles_sys)[1] == 0 and np.real(poles_sys)[0] < 0 and np.real(poles_sys)[1] < 0 and np.real(poles_sys)[0]!=np.real(poles_sys)[1]:
        display(Markdown('Sustav je **pretjerano prigušen** jer oba pola imaju samo negativne realne vrijednosti.'))
    elif math.isclose(0, np.imag(poles_sys)[0], abs_tol=10**-6) and math.isclose(0, np.imag(poles_sys)[1], abs_tol=10**-6) and np.real(poles_sys)[1] < 0 and np.real(poles_sys)[0]==np.real(poles_sys)[1]:
        display(Markdown('Sustav je **kritično prigušen** jer postoji dupli pol samo s negativnim realnim vrijednostima.'))
    elif np.real(poles_sys)[0] == 0 and np.real(poles_sys)[1] == 0:
        display(Markdown('Sustav je **neprigušen** jer polovi imaju samo imaginarne dijelove.'))
    elif np.imag(poles_sys)[0] != 0 and np.imag(poles_sys)[1] != 0 and np.real(poles_sys)[0] != 0 and np.real(poles_sys)[1] != 0:
        display(Markdown('Sustav je **nedovoljno prigušen** jer oba pola imaju negativne realne vrijednosti i kompleksne vrijednosti različite od nule.'))
    ax1[0].legend()
    ax1[1].legend()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.2190935907750067, 'fraction_numerical': 0.05323142933762403, 'mean_word_length': 4.642208774583963, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '662084', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 3623, 'n_tokens_neox': 3528, 'n_words': 559, 'path': 'ICCT_hr/examples/02/TD-10-Osnove_sustava_prvog_i_drugog_reda.ipynb', 'repo_name': 'ICCTerasmus/ICCT', 'size': '7458'}