|
6 | 6 | The following commands are provided: |
7 | 7 |
|
8 | 8 | Design and plot commands |
9 | | - dlqr - Discrete linear quadratic regulator |
| 9 | + dlqr - Discrete linear quadratic regulator |
10 | 10 | d2c - discrete to continous time conversion |
11 | 11 | full_obs - full order observer |
12 | 12 | red_obs - reduced order observer |
|
15 | 15 | set_aw - introduce anti-windup into controller |
16 | 16 | bb_dcgain - return the steady state value of the step response |
17 | 17 | placep - Pole placement (replacement for place) |
| 18 | + bb_c2d - Continous to discrete conversion |
18 | 19 |
|
19 | 20 | Old functions now corrected in python control |
20 | 21 | bb_dare - Solve Riccati equation for discrete time systems |
21 | 22 | |
22 | 23 | """ |
23 | 24 | from numpy import hstack, vstack, rank, imag, zeros, eye, mat, \ |
24 | | - array, shape, real, sort |
| 25 | + array, shape, real, sort, around |
25 | 26 | from scipy import poly |
26 | 27 | from scipy.linalg import inv, expm, eig, eigvals, logm |
27 | 28 | import scipy as sp |
@@ -82,6 +83,21 @@ def d2c(sys,method='zoh'): |
82 | 83 | B=s[0:n,n:n+nb] |
83 | 84 | C=c |
84 | 85 | 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)) |
85 | 101 | elif method=='bi': |
86 | 102 | a=mat(a) |
87 | 103 | b=mat(b) |
@@ -469,11 +485,6 @@ def set_aw(sys,poles): |
469 | 485 | def placep(A,B,P): |
470 | 486 | """Return the steady state value of the step response os sysmatrix K for |
471 | 487 | 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 |
477 | 488 |
|
478 | 489 | Usage |
479 | 490 | ===== |
@@ -590,3 +601,89 @@ def bb_dcgain(sys): |
590 | 601 | gm=-c*inv(a)*b+d |
591 | 602 | return array(gm) |
592 | 603 |
|
| 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