9
9
import control as ctrl
10
10
from control .xferfcn import TransferFunction
11
11
from control .statesp import StateSpace
12
- from control .bdalg import feedback
12
+ from control .bdalg import feedback , append , connect
13
13
from control .lti import zero , pole
14
14
15
15
class TestFeedback (unittest .TestCase ):
@@ -23,7 +23,9 @@ def setUp(self):
23
23
# Two random SISO systems.
24
24
self .sys1 = TransferFunction ([1 , 2 ], [1 , 2 , 3 ])
25
25
self .sys2 = StateSpace ([[1. , 4. ], [3. , 2. ]], [[1. ], [- 4. ]],
26
- [[1. , 0. ]], [[0. ]])
26
+ [[1. , 0. ]], [[0. ]]) # 2 states, SISO
27
+ self .sys3 = StateSpace ([[- 1. ]], [[1. ]], [[1. ]], [[0. ]]) # 1 state, SISO
28
+
27
29
# Two random scalars.
28
30
self .x1 = 2.5
29
31
self .x2 = - 3.
@@ -192,50 +194,50 @@ def testLists(self):
192
194
sys1_2 = ctrl .series (sys1 , sys2 )
193
195
np .testing .assert_array_almost_equal (sort (pole (sys1_2 )), [- 4. , - 2. ])
194
196
np .testing .assert_array_almost_equal (sort (zero (sys1_2 )), [- 3. , - 1. ])
195
-
197
+
196
198
sys1_3 = ctrl .series (sys1 , sys2 , sys3 );
197
199
np .testing .assert_array_almost_equal (sort (pole (sys1_3 )),
198
200
[- 6. , - 4. , - 2. ])
199
- np .testing .assert_array_almost_equal (sort (zero (sys1_3 )),
201
+ np .testing .assert_array_almost_equal (sort (zero (sys1_3 )),
200
202
[- 5. , - 3. , - 1. ])
201
-
203
+
202
204
sys1_4 = ctrl .series (sys1 , sys2 , sys3 , sys4 );
203
205
np .testing .assert_array_almost_equal (sort (pole (sys1_4 )),
204
206
[- 8. , - 6. , - 4. , - 2. ])
205
207
np .testing .assert_array_almost_equal (sort (zero (sys1_4 )),
206
208
[- 7. , - 5. , - 3. , - 1. ])
207
-
209
+
208
210
sys1_5 = ctrl .series (sys1 , sys2 , sys3 , sys4 , sys5 );
209
211
np .testing .assert_array_almost_equal (sort (pole (sys1_5 )),
210
212
[- 8. , - 6. , - 4. , - 2. , - 0. ])
211
- np .testing .assert_array_almost_equal (sort (zero (sys1_5 )),
213
+ np .testing .assert_array_almost_equal (sort (zero (sys1_5 )),
212
214
[- 9. , - 7. , - 5. , - 3. , - 1. ])
213
215
214
- # Parallel
216
+ # Parallel
215
217
sys1_2 = ctrl .parallel (sys1 , sys2 )
216
218
np .testing .assert_array_almost_equal (sort (pole (sys1_2 )), [- 4. , - 2. ])
217
219
np .testing .assert_array_almost_equal (sort (zero (sys1_2 )),
218
220
sort (zero (sys1 + sys2 )))
219
-
221
+
220
222
sys1_3 = ctrl .parallel (sys1 , sys2 , sys3 );
221
223
np .testing .assert_array_almost_equal (sort (pole (sys1_3 )),
222
224
[- 6. , - 4. , - 2. ])
223
- np .testing .assert_array_almost_equal (sort (zero (sys1_3 )),
225
+ np .testing .assert_array_almost_equal (sort (zero (sys1_3 )),
224
226
sort (zero (sys1 + sys2 + sys3 )))
225
-
227
+
226
228
sys1_4 = ctrl .parallel (sys1 , sys2 , sys3 , sys4 );
227
229
np .testing .assert_array_almost_equal (sort (pole (sys1_4 )),
228
230
[- 8. , - 6. , - 4. , - 2. ])
229
- np .testing .assert_array_almost_equal (sort (zero (sys1_4 )),
230
- sort (zero (sys1 + sys2 +
231
+ np .testing .assert_array_almost_equal (sort (zero (sys1_4 )),
232
+ sort (zero (sys1 + sys2 +
231
233
sys3 + sys4 )))
232
234
233
-
235
+
234
236
sys1_5 = ctrl .parallel (sys1 , sys2 , sys3 , sys4 , sys5 );
235
237
np .testing .assert_array_almost_equal (sort (pole (sys1_5 )),
236
238
[- 8. , - 6. , - 4. , - 2. , - 0. ])
237
- np .testing .assert_array_almost_equal (sort (zero (sys1_5 )),
238
- sort (zero (sys1 + sys2 +
239
+ np .testing .assert_array_almost_equal (sort (zero (sys1_5 )),
240
+ sort (zero (sys1 + sys2 +
239
241
sys3 + sys4 + sys5 )))
240
242
def testMimoSeries (self ):
241
243
"""regression: bdalg.series reverses order of arguments"""
@@ -270,6 +272,56 @@ def test_feedback_args(self):
270
272
sys = ctrl .feedback (1 , frd )
271
273
self .assertTrue (isinstance (sys , ctrl .FRD ))
272
274
275
+ def testConnect (self ):
276
+ sys = append (self .sys2 , self .sys3 ) # two siso systems
277
+
278
+ # should not raise error
279
+ connect (sys , [[1 , 2 ], [2 , - 2 ]], [2 ], [1 , 2 ])
280
+ connect (sys , [[1 , 2 ], [2 , 0 ]], [2 ], [1 , 2 ])
281
+ connect (sys , [[1 , 2 , 0 ], [2 , - 2 , 1 ]], [2 ], [1 , 2 ])
282
+ connect (sys , [[1 , 2 ], [2 , - 2 ]], [2 , 1 ], [1 ])
283
+ sys3x3 = append (sys , self .sys3 ) # 3x3 mimo
284
+ connect (sys3x3 , [[1 , 2 , 0 ], [2 , - 2 , 1 ], [3 , - 3 , 0 ]], [2 ], [1 , 2 ])
285
+ connect (sys3x3 , [[1 , 2 , 0 ], [2 , - 2 , 1 ], [3 , - 3 , 0 ]], [1 , 2 , 3 ], [3 ])
286
+ connect (sys3x3 , [[1 , 2 , 0 ], [2 , - 2 , 1 ], [3 , - 3 , 0 ]], [2 , 3 ], [2 , 1 ])
287
+
288
+ # feedback interconnection out of bounds: input too high
289
+ Q = [[1 , 3 ], [2 , - 2 ]]
290
+ with self .assertRaises (IndexError ):
291
+ connect (sys , Q , [2 ], [1 , 2 ])
292
+ # feedback interconnection out of bounds: input too low
293
+ Q = [[0 , 2 ], [2 , - 2 ]]
294
+ with self .assertRaises (IndexError ):
295
+ connect (sys , Q , [2 ], [1 , 2 ])
296
+
297
+ # feedback interconnection out of bounds: output too high
298
+ Q = [[1 , 2 ], [2 , - 3 ]]
299
+ with self .assertRaises (IndexError ):
300
+ connect (sys , Q , [2 ], [1 , 2 ])
301
+ Q = [[1 , 2 ], [2 , 4 ]]
302
+ with self .assertRaises (IndexError ):
303
+ connect (sys , Q , [2 ], [1 , 2 ])
304
+
305
+ # input/output index testing
306
+ Q = [[1 , 2 ], [2 , - 2 ]] # OK interconnection
307
+
308
+ # input index is out of bounds: too high
309
+ with self .assertRaises (IndexError ):
310
+ connect (sys , Q , [3 ], [1 , 2 ])
311
+ # input index is out of bounds: too low
312
+ with self .assertRaises (IndexError ):
313
+ connect (sys , Q , [0 ], [1 , 2 ])
314
+ with self .assertRaises (IndexError ):
315
+ connect (sys , Q , [- 2 ], [1 , 2 ])
316
+ # output index is out of bounds: too high
317
+ with self .assertRaises (IndexError ):
318
+ connect (sys , Q , [2 ], [1 , 3 ])
319
+ # output index is out of bounds: too low
320
+ with self .assertRaises (IndexError ):
321
+ connect (sys , Q , [2 ], [1 , 0 ])
322
+ with self .assertRaises (IndexError ):
323
+ connect (sys , Q , [2 ], [1 , - 1 ])
324
+
273
325
274
326
if __name__ == "__main__" :
275
327
unittest .main ()
0 commit comments