Skip to content

Commit 90133e8

Browse files
committed
Update yottalab.py
1 parent 32b5b3e commit 90133e8

1 file changed

Lines changed: 104 additions & 7 deletions

File tree

external/yottalab.py

Lines changed: 104 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
The following commands are provided:
77
88
Design and plot commands
9-
dlqr - Discrete linear quadratic regulator
9+
dlqr - Discrete linear quadratic regulator
1010
d2c - discrete to continous time conversion
1111
full_obs - full order observer
1212
red_obs - reduced order observer
@@ -15,13 +15,14 @@
1515
set_aw - introduce anti-windup into controller
1616
bb_dcgain - return the steady state value of the step response
1717
placep - Pole placement (replacement for place)
18+
bb_c2d - Continous to discrete conversion
1819
1920
Old functions now corrected in python control
2021
bb_dare - Solve Riccati equation for discrete time systems
2122
2223
"""
2324
from numpy import hstack, vstack, rank, imag, zeros, eye, mat, \
24-
array, shape, real, sort
25+
array, shape, real, sort, around
2526
from scipy import poly
2627
from scipy.linalg import inv, expm, eig, eigvals, logm
2728
import scipy as sp
@@ -82,6 +83,21 @@ def d2c(sys,method='zoh'):
8283
B=s[0:n,n:n+nb]
8384
C=c
8485
D=d
86+
elif method=='foh':
87+
a=mat(a)
88+
b=mat(b)
89+
c=mat(c)
90+
d=mat(d)
91+
Id = mat(eye(n))
92+
A = logm(a)/Ts
93+
A = real(around(A,12))
94+
Amat = mat(A)
95+
B = (a-Id)**(-2)*Amat**2*b*Ts
96+
B = real(around(B,12))
97+
Bmat = mat(B)
98+
C = c
99+
D = d - C*(Amat**(-2)/Ts*(a-Id)-Amat**(-1))*Bmat
100+
D = real(around(D,12))
85101
elif method=='bi':
86102
a=mat(a)
87103
b=mat(b)
@@ -469,11 +485,6 @@ def set_aw(sys,poles):
469485
def placep(A,B,P):
470486
"""Return the steady state value of the step response os sysmatrix K for
471487
pole placement
472-
473-
This function require a wrapper with fortran source for solving the
474-
pole placement problem (otherwise there are bad conditioned results
475-
by MIMO systems!)
476-
Please ask the author for complete sources roberto.bucher@supsi.ch
477488
478489
Usage
479490
=====
@@ -590,3 +601,89 @@ def bb_dcgain(sys):
590601
gm=-c*inv(a)*b+d
591602
return array(gm)
592603

604+
def bb_c2d(sys,Ts,method='zoh'):
605+
"""Continous to discrete conversion with ZOH method
606+
607+
Call:
608+
sysd=c2d(sys,Ts,method='zoh')
609+
610+
Parameters
611+
----------
612+
sys : System in statespace or Tf form
613+
Ts: Sampling Time
614+
method: 'zoh', 'bi' or 'matched'
615+
616+
Returns
617+
-------
618+
sysd: ss or Tf system
619+
Discrete system
620+
621+
"""
622+
flag = 0
623+
if isinstance(sys, TransferFunction):
624+
sys=tf2ss(sys)
625+
flag=1
626+
627+
a=sys.A
628+
b=sys.B
629+
c=sys.C
630+
d=sys.D
631+
n=shape(a)[0]
632+
nb=shape(b)[1]
633+
nc=shape(c)[0]
634+
635+
if method=='zoh':
636+
ztmp=zeros((nb,n+nb))
637+
tmp=hstack((a,b))
638+
tmp=vstack((tmp,ztmp))
639+
tmp=expm(tmp*Ts)
640+
A=tmp[0:n,0:n]
641+
B=tmp[0:n,n:n+nb]
642+
C=c
643+
D=d
644+
elif method=='foh':
645+
a=mat(a)
646+
b=mat(b)
647+
c=mat(c)
648+
d=mat(d)
649+
Id = mat(eye(n))
650+
A = expm(a*Ts)
651+
B = a**(-2)/Ts*(expm(a*Ts)-Id)**2*b
652+
C = c
653+
D = d + c*(a**(-2)/Ts*(expm(a*Ts)-Id)-a**(-1))*b
654+
elif method=='bi':
655+
a=mat(a)
656+
b=mat(b)
657+
c=mat(c)
658+
d=mat(d)
659+
IT=mat(2/Ts*eye(n,n))
660+
A=(IT+a)*inv(IT-a)
661+
iab=inv(IT-a)*b
662+
tk=2/sqrt(Ts)
663+
B=tk*iab
664+
C=tk*(c*inv(IT-a))
665+
D=d+c*iab
666+
elif method=='matched':
667+
if nb!=1 and nc!=1:
668+
print "System is not SISO"
669+
return
670+
p=exp(sys.poles*Ts)
671+
z=exp(sys.zeros*Ts)
672+
infinite_zeros = len(sys.poles) - len(sys.zeros) - 1
673+
for i in range(0,infinite_zeros):
674+
z=hstack((z,-1))
675+
[A,B,C,D]=zpk2ss(z,p,1)
676+
sysd=StateSpace(A,B,C,D,Ts)
677+
cg = dcgain(sys)
678+
dg = dcgain(sysd)
679+
[A,B,C,D]=zpk2ss(z,p,cg/dg)
680+
else:
681+
print "Method not supported"
682+
return
683+
684+
sysd=StateSpace(A,B,C,D,Ts)
685+
if flag==1:
686+
sysd=ss2tf(sysd)
687+
return sysd
688+
689+

0 commit comments

Comments
 (0)