Skip to content

Commit 98e71cb

Browse files
yuina822Yuichi NAGAYAMA
authored andcommitted
Add function to convert a system into observable canonical form
1 parent 7b07af3 commit 98e71cb

File tree

1 file changed

+51
-3
lines changed

1 file changed

+51
-3
lines changed

control/canonical.py

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
from .exception import ControlNotImplemented
55
from .lti import issiso
66
from .statesp import StateSpace
7-
from .statefbk import ctrb
7+
from .statefbk import ctrb, obsv
88

99
from numpy import zeros, shape, poly
1010
from numpy.linalg import inv
1111

12-
__all__ = ['canonical_form', 'reachable_form']
12+
__all__ = ['canonical_form', 'reachable_form', 'observable_form']
1313

1414
def canonical_form(xsys, form='reachable'):
1515
"""Convert a system into canonical form
@@ -21,7 +21,7 @@ def canonical_form(xsys, form='reachable'):
2121
form : String
2222
Canonical form for transformation. Chosen from:
2323
* 'reachable' - reachable canonical form
24-
* 'observable' - observable canonical form [not implemented]
24+
* 'observable' - observable canonical form
2525
* 'modal' - modal canonical form [not implemented]
2626
2727
Returns
@@ -35,6 +35,8 @@ def canonical_form(xsys, form='reachable'):
3535
# Call the appropriate tranformation function
3636
if form == 'reachable':
3737
return reachable_form(xsys)
38+
elif form == 'observable':
39+
return observable_form(xsys)
3840
else:
3941
raise ControlNotImplemented(
4042
"Canonical form '%s' not yet implemented" % form)
@@ -85,3 +87,49 @@ def reachable_form(xsys):
8587
zsys.C = xsys.C * inv(Tzx)
8688

8789
return zsys, Tzx
90+
91+
92+
def observable_form(xsys):
93+
"""Convert a system into observable canonical form
94+
95+
Parameters
96+
----------
97+
xsys : StateSpace object
98+
System to be transformed, with state `x`
99+
100+
Returns
101+
-------
102+
zsys : StateSpace object
103+
System in observable canonical form, with state `z`
104+
T : matrix
105+
Coordinate transformation: z = T * x
106+
"""
107+
# Check to make sure we have a SISO system
108+
if not issiso(xsys):
109+
raise ControlNotImplemented(
110+
"Canonical forms for MIMO systems not yet supported")
111+
112+
# Create a new system, starting with a copy of the old one
113+
zsys = StateSpace(xsys)
114+
115+
# Generate the system matrices for the desired canonical form
116+
zsys.C = zeros(shape(xsys.C))
117+
zsys.C[0, 0] = 1
118+
zsys.A = zeros(shape(xsys.A))
119+
Apoly = poly(xsys.A) # characteristic polynomial
120+
for i in range(0, xsys.states):
121+
zsys.A[i, 0] = -Apoly[i+1] / Apoly[0]
122+
if (i+1 < xsys.states):
123+
zsys.A[i, i+1] = 1
124+
125+
# Compute the observability matrices for each set of states
126+
Wrx = obsv(xsys.A, xsys.C)
127+
Wrz = obsv(zsys.A, zsys.C)
128+
129+
# Transformation from one form to another
130+
Tzx = inv(Wrz) * Wrx
131+
132+
# Finally, compute the output matrix
133+
zsys.B = Tzx * xsys.B
134+
135+
return zsys, Tzx

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy