|
9 | 9 | from control.statefbk import ctrb, obsv, place, place_varga, lqr, gram, acker
|
10 | 10 | from control.matlab import *
|
11 | 11 | from control.exception import slycot_check, ControlDimension
|
| 12 | +from control.mateqn import care, dare |
12 | 13 |
|
13 | 14 | class TestStatefbk(unittest.TestCase):
|
14 | 15 | """Test state feedback functions"""
|
@@ -298,6 +299,37 @@ def test_LQR_3args(self):
|
298 | 299 | K, S, poles = lqr(sys, Q, R)
|
299 | 300 | self.check_LQR(K, S, poles, Q, R)
|
300 | 301 |
|
| 302 | + @unittest.skipIf(not slycot_check(), "slycot not installed") |
| 303 | + def test_care(self): |
| 304 | + #unit test for stabilizing and anti-stabilizing feedbacks |
| 305 | + #continuous-time |
| 306 | + |
| 307 | + A = np.diag([1,-1]) |
| 308 | + B = np.identity(2) |
| 309 | + Q = np.identity(2) |
| 310 | + R = np.identity(2) |
| 311 | + S = 0 * B |
| 312 | + E = np.identity(2) |
| 313 | + X, L , G = care(A, B, Q, R, S, E, stabilizing=True) |
| 314 | + assert np.all(np.real(L) < 0) |
| 315 | + X, L , G = care(A, B, Q, R, S, E, stabilizing=False) |
| 316 | + assert np.all(np.real(L) > 0) |
| 317 | + |
| 318 | + @unittest.skipIf(not slycot_check(), "slycot not installed") |
| 319 | + def test_dare(self): |
| 320 | + #discrete-time |
| 321 | + A = np.diag([0.5,2]) |
| 322 | + B = np.identity(2) |
| 323 | + Q = np.identity(2) |
| 324 | + R = np.identity(2) |
| 325 | + S = 0 * B |
| 326 | + E = np.identity(2) |
| 327 | + X, L , G = dare(A, B, Q, R, S, E, stabilizing=True) |
| 328 | + assert np.all(np.abs(L) < 1) |
| 329 | + X, L , G = dare(A, B, Q, R, S, E, stabilizing=False) |
| 330 | + assert np.all(np.abs(L) > 1) |
| 331 | + |
| 332 | + |
301 | 333 | def test_suite():
|
302 | 334 | return unittest.TestLoader().loadTestsFromTestCase(TestStatefbk)
|
303 | 335 |
|
|
0 commit comments