Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit077a8bc

Browse files
authored
Merge pull request#200 from ipa-lth/master
Fix canonical form 'observable'
2 parents81ebbcf +5009e92 commit077a8bc

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

‎control/canonical.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,10 @@ def observable_form(xsys):
133133
Wrz=obsv(zsys.A,zsys.C)
134134

135135
# Transformation from one form to another
136-
Tzx=inv(Wrz)*Wrx
136+
Tzx=solve(Wrz,Wrx)# matrix left division, Tzx = inv(Wrz) * Wrx
137+
138+
ifmatrix_rank(Tzx)!=xsys.states:
139+
raiseValueError("Transformation matrix singular to working precision.")
137140

138141
# Finally, compute the output matrix
139142
zsys.B=Tzx*xsys.B

‎control/tests/canonical_test.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,47 @@ def test_unreachable_system(self):
5252

5353
# Check if an exception is raised
5454
np.testing.assert_raises(ValueError,canonical_form,sys,"reachable")
55+
56+
deftest_observable_form(self):
57+
"""Test the observable canonical form"""
58+
59+
# Create a system in the observable canonical form
60+
coeffs= [1.0,2.0,3.0,4.0,1.0]
61+
A_true=np.polynomial.polynomial.polycompanion(coeffs)
62+
A_true=np.fliplr(np.flipud(A_true))
63+
B_true=np.matrix("1.0 1.0 1.0 1.0").T
64+
C_true=np.matrix("1.0 0.0 0.0 0.0")
65+
D_true=42.0
66+
67+
# Perform a coordinate transform with a random invertible matrix
68+
T_true=np.matrix([[-0.27144004,-0.39933167,0.75634684,0.44135471],
69+
[-0.74855725,-0.39136285,-0.18142339,-0.50356997],
70+
[-0.40688007,0.81416369,0.38002113,-0.16483334],
71+
[-0.44769516,0.15654653,-0.50060858,0.72419146]])
72+
A=np.linalg.solve(T_true,A_true)*T_true
73+
B=np.linalg.solve(T_true,B_true)
74+
C=C_true*T_true
75+
D=D_true
76+
77+
# Create a state space system and convert it to the observable canonical form
78+
sys_check,T_check=canonical_form(ss(A,B,C,D),"observable")
79+
80+
# Check against the true values
81+
np.testing.assert_array_almost_equal(sys_check.A,A_true)
82+
np.testing.assert_array_almost_equal(sys_check.B,B_true)
83+
np.testing.assert_array_almost_equal(sys_check.C,C_true)
84+
np.testing.assert_array_almost_equal(sys_check.D,D_true)
85+
np.testing.assert_array_almost_equal(T_check,T_true)
86+
87+
deftest_unobservable_system(self):
88+
"""Test observable canonical form with an unobservable system"""
89+
90+
# Create an unobservable system
91+
A=np.matrix("1.0 2.0 2.0; 4.0 5.0 5.0; 7.0 8.0 8.0")
92+
B=np.matrix("1.0 1.0 1.0").T
93+
C=np.matrix("1.0 1.0 1.0")
94+
D=42.0
95+
sys=ss(A,B,C,D)
96+
97+
# Check if an exception is raised
98+
np.testing.assert_raises(ValueError,canonical_form,sys,"observable")

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp