From 8e8bf089c9bde386d337360f23f49d230eca3576 Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Sun, 29 Dec 2019 21:59:58 -0800 Subject: [PATCH 1/2] fix printing for systems w/ unspecified inputs, outputs, states --- control/iosys.py | 18 +++++++----------- control/tests/iosys_test.py | 27 ++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/control/iosys.py b/control/iosys.py index a0a0d08f2..1e3458058 100644 --- a/control/iosys.py +++ b/control/iosys.py @@ -212,12 +212,12 @@ def __repr__(self): def __str__(self): """String representation of an input/output system""" - str = "System: " + (self.name if self.name else "(none)") + "\n" - str += "Inputs (%d): " % self.ninputs + str = "System: " + (self.name if self.name else "(None)") + "\n" + str += "Inputs (%s): " % self.ninputs for key in self.input_index: str += key + ", " - str += "\nOutputs (%d): " % self.noutputs + str += "\nOutputs (%s): " % self.noutputs for key in self.output_index: str += key + ", " - str += "\nStates (%d): " % self.nstates + str += "\nStates (%s): " % self.nstates for key in self.state_index: str += key + ", " return str @@ -317,13 +317,8 @@ def __add__(sys1, sys2): ninputs = sys1.ninputs noutputs = sys1.noutputs - # Make sure timebase are compatible - dt = _find_timebase(sys1, sys2) - if dt is False: - raise ValueError("System timebases are not compabile") - # Create a new system to handle the composition - newsys = InterconnectedSystem((sys1, sys2), dt=dt) + newsys = InterconnectedSystem((sys1, sys2)) # Set up the input map newsys.set_input_map(np.concatenate( @@ -937,6 +932,7 @@ def __init__(self, syslist, connections=[], inplist=[], outlist=[], system_count = 0 for sys in syslist: # Make sure time bases are consistent + # TODO: Use lti._find_timebase() instead? if dt is None and sys.dt is not None: # Timebase was not specified; set to match this system dt = sys.dt @@ -948,7 +944,7 @@ def __init__(self, syslist, connections=[], inplist=[], outlist=[], sys.nstates is None: raise TypeError("System '%s' must define number of inputs, " "outputs, states in order to be connected" % - sys) + sys.name) # Keep track of the offsets into the states, inputs, outputs self.input_offset.append(ninputs) diff --git a/control/tests/iosys_test.py b/control/tests/iosys_test.py index 00733aa74..d8bf3dd3b 100644 --- a/control/tests/iosys_test.py +++ b/control/tests/iosys_test.py @@ -100,6 +100,32 @@ def test_ss2io(self): np.testing.assert_array_equal(linsys.C, iosys_named.C) np.testing.assert_array_equal(linsys.D, iosys_named.D) + # Make sure unspecified inputs/outputs/states are handled properly + def test_iosys_unspecified(self): + # System with unspecified inputs and outputs + sys = ios.NonlinearIOSystem(secord_update, secord_output) + np.testing.assert_raises(TypeError, sys.__mul__, sys) + + # Make sure we can print various types of I/O systems + def test_iosys_print(self): + # Send the output to /dev/null + import os + f = open(os.devnull,"w") + + # Simple I/O system + iosys = ct.ss2io(self.siso_linsys) + print(iosys, file=f) + + # I/O system without ninputs, noutputs + ios_unspecified = ios.NonlinearIOSystem(secord_update, secord_output) + print(ios_unspecified, file=f) + + # I/O system with derived inputs and outputs + ios_linearized = ios.linearize(ios_unspecified, [0, 0], [0]) + print(ios_linearized, file=f) + + f.close() + @unittest.skipIf(StrictVersion(sp.__version__) < "1.0", "requires SciPy 1.0 or greater") def test_nonlinear_iosys(self): @@ -832,7 +858,6 @@ def test_lineariosys_statespace(self): np.testing.assert_array_equal(io_feedback.C, ss_feedback.C) np.testing.assert_array_equal(io_feedback.D, ss_feedback.D) - def test_duplicates(self): nlios = ios.NonlinearIOSystem(None, \ lambda t, x, u, params: u*u, inputs=1, outputs=1) From 47112b4ce18c565ad96e7b6d4afa8e1406c17fdf Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Sun, 29 Dec 2019 22:09:10 -0800 Subject: [PATCH 2/2] fix print test for python2.7 --- control/tests/iosys_test.py | 1 + 1 file changed, 1 insertion(+) diff --git a/control/tests/iosys_test.py b/control/tests/iosys_test.py index d8bf3dd3b..aaf2243c1 100644 --- a/control/tests/iosys_test.py +++ b/control/tests/iosys_test.py @@ -8,6 +8,7 @@ # operations on input/output systems. Separate unit tests should be # created for that purpose. +from __future__ import print_function import unittest import warnings import numpy as np