|
8 | 8 | import numpy as np |
9 | 9 | from control.statefbk import ctrb, obsv, place, lqr, gram, acker |
10 | 10 | from control.matlab import * |
11 | | -from control.exception import slycot_check |
| 11 | +from control.exception import slycot_check, ControlDimension |
12 | 12 |
|
13 | 13 | class TestStatefbk(unittest.TestCase): |
14 | 14 | """Test state feedback functions""" |
@@ -157,6 +157,51 @@ def testAcker(self): |
157 | 157 | np.testing.assert_array_almost_equal(np.sort(poles), |
158 | 158 | np.sort(placed), decimal=4) |
159 | 159 |
|
| 160 | + def testPlace(self): |
| 161 | + # Matrices shamelessly stolen from scipy example code. |
| 162 | + A = np.array([[1.380, -0.2077, 6.715, -5.676], |
| 163 | + [-0.5814, -4.290, 0, 0.6750], |
| 164 | + [1.067, 4.273, -6.654, 5.893], |
| 165 | + [0.0480, 4.273, 1.343, -2.104]]) |
| 166 | + |
| 167 | + B = np.array([[0, 5.679], |
| 168 | + [1.136, 1.136], |
| 169 | + [0, 0,], |
| 170 | + [-3.146, 0]]) |
| 171 | + P = np.array([-0.5+1j, -0.5-1j, -5.0566, -8.6659]) |
| 172 | + K = place(A, B, P) |
| 173 | + P_placed = np.linalg.eigvals(A - B.dot(K)) |
| 174 | + # No guarantee of the ordering, so sort them |
| 175 | + P.sort() |
| 176 | + P_placed.sort() |
| 177 | + np.testing.assert_array_almost_equal(P, P_placed) |
| 178 | + |
| 179 | + # Test that the dimension checks work. |
| 180 | + np.testing.assert_raises(ControlDimension, place, A[1:, :], B, P) |
| 181 | + np.testing.assert_raises(ControlDimension, place, A, B[1:, :], P) |
| 182 | + |
| 183 | + # Check that we get an error if we ask for too many poles in the same |
| 184 | + # location. Here, rank(B) = 2, so lets place three at the same spot. |
| 185 | + P_repeated = np.array([-0.5, -0.5, -0.5, -8.6659]) |
| 186 | + np.testing.assert_raises(ValueError, place, A, B, P_repeated) |
| 187 | + |
| 188 | + @unittest.skipIf(not slycot_check(), "slycot not installed") |
| 189 | + def testPlace_varga(self): |
| 190 | + A = np.array([[1., -2.], [3., -4.]]) |
| 191 | + B = np.array([[5.], [7.]]) |
| 192 | + |
| 193 | + P = np.array([-2., -2.]) |
| 194 | + K = place_varga(A, B, P) |
| 195 | + P_placed = np.linalg.eigvals(A - B.dot(K)) |
| 196 | + # No guarantee of the ordering, so sort them |
| 197 | + P.sort() |
| 198 | + P_placed.sort() |
| 199 | + np.testing.assert_array_almost_equal(P, P_placed) |
| 200 | + |
| 201 | + # Test that the dimension checks work. |
| 202 | + np.testing.assert_raises(ControlDimension, place, A[1:, :], B, P) |
| 203 | + np.testing.assert_raises(ControlDimension, place, A, B[1:, :], P) |
| 204 | + |
160 | 205 | def check_LQR(self, K, S, poles, Q, R): |
161 | 206 | S_expected = np.array(np.sqrt(Q * R)) |
162 | 207 | K_expected = S_expected / R |
|
0 commit comments