@@ -612,7 +612,7 @@ class LinearIOSystem(InputOutputSystem, StateSpace):
612
612
613
613
"""
614
614
def __init__ (self , linsys , inputs = None , outputs = None , states = None ,
615
- name = None ):
615
+ name = None , ** kwargs ):
616
616
"""Create an I/O system from a state space linear system.
617
617
618
618
Converts a :class:`~control.StateSpace` system into an
@@ -658,6 +658,10 @@ def __init__(self, linsys, inputs=None, outputs=None, states=None,
658
658
if not isinstance (linsys , StateSpace ):
659
659
raise TypeError ("Linear I/O system must be a state space object" )
660
660
661
+ # Look for 'input' and 'output' parameter name variants
662
+ inputs = _parse_signal_parameter (inputs , 'input' , kwargs )
663
+ outputs = _parse_signal_parameter (outputs , 'output' , kwargs , end = True )
664
+
661
665
# Create the I/O system object
662
666
super (LinearIOSystem , self ).__init__ (
663
667
inputs = linsys .ninputs , outputs = linsys .noutputs ,
@@ -707,8 +711,7 @@ class NonlinearIOSystem(InputOutputSystem):
707
711
708
712
"""
709
713
def __init__ (self , updfcn , outfcn = None , inputs = None , outputs = None ,
710
- states = None , params = {},
711
- name = None , ** kwargs ):
714
+ states = None , params = {}, name = None , ** kwargs ):
712
715
"""Create a nonlinear I/O system given update and output functions.
713
716
714
717
Creates an :class:`~control.InputOutputSystem` for a nonlinear system
@@ -775,17 +778,25 @@ def __init__(self, updfcn, outfcn=None, inputs=None, outputs=None,
775
778
Nonlinear system represented as an input/output system.
776
779
777
780
"""
781
+ # Look for 'input' and 'output' parameter name variants
782
+ inputs = _parse_signal_parameter (inputs , 'input' , kwargs )
783
+ outputs = _parse_signal_parameter (outputs , 'output' , kwargs )
784
+
778
785
# Store the update and output functions
779
786
self .updfcn = updfcn
780
787
self .outfcn = outfcn
781
788
782
789
# Initialize the rest of the structure
783
- dt = kwargs .get ('dt' , config .defaults ['control.default_dt' ])
790
+ dt = kwargs .pop ('dt' , config .defaults ['control.default_dt' ])
784
791
super (NonlinearIOSystem , self ).__init__ (
785
792
inputs = inputs , outputs = outputs , states = states ,
786
793
params = params , dt = dt , name = name
787
794
)
788
795
796
+ # Make sure all input arguments got parsed
797
+ if kwargs :
798
+ raise TypeError ("unknown parameters %s" % kwargs )
799
+
789
800
# Check to make sure arguments are consistent
790
801
if updfcn is None :
791
802
if self .nstates is None :
@@ -834,7 +845,7 @@ class InterconnectedSystem(InputOutputSystem):
834
845
"""
835
846
def __init__ (self , syslist , connections = [], inplist = [], outlist = [],
836
847
inputs = None , outputs = None , states = None ,
837
- params = {}, dt = None , name = None ):
848
+ params = {}, dt = None , name = None , ** kwargs ):
838
849
"""Create an I/O system from a list of systems + connection info.
839
850
840
851
The InterconnectedSystem class is used to represent an input/output
@@ -846,6 +857,10 @@ def __init__(self, syslist, connections=[], inplist=[], outlist=[],
846
857
See :func:`~control.interconnect` for a list of parameters.
847
858
848
859
"""
860
+ # Look for 'input' and 'output' parameter name variants
861
+ inputs = _parse_signal_parameter (inputs , 'input' , kwargs )
862
+ outputs = _parse_signal_parameter (outputs , 'output' , kwargs , end = True )
863
+
849
864
# Convert input and output names to lists if they aren't already
850
865
if not isinstance (inplist , (list , tuple )):
851
866
inplist = [inplist ]
@@ -1810,6 +1825,15 @@ def linearize(sys, xeq, ueq=[], t=0, params={}, **kw):
1810
1825
return sys .linearize (xeq , ueq , t = t , params = params , ** kw )
1811
1826
1812
1827
1828
+ # Utility function to parse a signal parameter
1829
+ def _parse_signal_parameter (value , name , kwargs , end = False ):
1830
+ if value is None and name in kwargs :
1831
+ value = list (kwargs .pop (name ))
1832
+ if end and kwargs :
1833
+ raise TypeError ("unknown parameters %s" % kwargs )
1834
+ return value
1835
+
1836
+
1813
1837
def _find_size (sysval , vecval ):
1814
1838
"""Utility function to find the size of a system parameter
1815
1839
@@ -1849,7 +1873,7 @@ def tf2io(*args, **kwargs):
1849
1873
# Function to create an interconnected system
1850
1874
def interconnect (syslist , connections = None , inplist = [], outlist = [],
1851
1875
inputs = None , outputs = None , states = None ,
1852
- params = {}, dt = None , name = None ):
1876
+ params = {}, dt = None , name = None , ** kwargs ):
1853
1877
"""Interconnect a set of input/output systems.
1854
1878
1855
1879
This function creates a new system that is an interconnection of a set of
@@ -1995,7 +2019,7 @@ def interconnect(syslist, connections=None, inplist=[], outlist=[],
1995
2019
>>> P = control.tf2io(control.tf(1, [1, 0]), inputs='u', outputs='y')
1996
2020
>>> C = control.tf2io(control.tf(10, [1, 1]), inputs='e', outputs='u')
1997
2021
>>> sumblk = control.summing_junction(inputs=['r', '-y'], output='e')
1998
- >>> T = control.interconnect([P, C, sumblk], inplist ='r', outlist ='y')
2022
+ >>> T = control.interconnect([P, C, sumblk], input ='r', output ='y')
1999
2023
2000
2024
Notes
2001
2025
-----
@@ -2020,7 +2044,14 @@ def interconnect(syslist, connections=None, inplist=[], outlist=[],
2020
2044
treated as both a :class:`~control.StateSpace` system as well as an
2021
2045
:class:`~control.InputOutputSystem`.
2022
2046
2047
+ The `input` and `output` keywords can be used instead of `inputs` and
2048
+ `outputs`, for more natural naming of SISO systems.
2049
+
2023
2050
"""
2051
+ # Look for 'input' and 'output' parameter name variants
2052
+ inputs = _parse_signal_parameter (inputs , 'input' , kwargs )
2053
+ outputs = _parse_signal_parameter (outputs , 'output' , kwargs , end = True )
2054
+
2024
2055
# If connections was not specified, set up default connection list
2025
2056
if connections is None :
2026
2057
# For each system input, look for outputs with the same name
@@ -2037,6 +2068,12 @@ def interconnect(syslist, connections=None, inplist=[], outlist=[],
2037
2068
# Use an empty connections list
2038
2069
connections = []
2039
2070
2071
+ # If inplist/outlist is not present, try using inputs/outputs instead
2072
+ if not inplist and inputs is not None :
2073
+ inplist = list (inputs )
2074
+ if not outlist and outputs is not None :
2075
+ outlist = list (outputs )
2076
+
2040
2077
# Process input list
2041
2078
if not isinstance (inplist , (list , tuple )):
2042
2079
inplist = [inplist ]
@@ -2106,7 +2143,9 @@ def interconnect(syslist, connections=None, inplist=[], outlist=[],
2106
2143
2107
2144
2108
2145
# Summing junction
2109
- def summing_junction (inputs , output = 'y' , dimension = None , name = None , prefix = 'u' ):
2146
+ def summing_junction (
2147
+ inputs = None , output = None , dimension = None , name = None ,
2148
+ prefix = 'u' , ** kwargs ):
2110
2149
"""Create a summing junction as an input/output system.
2111
2150
2112
2151
This function creates a static input/output system that outputs the sum of
@@ -2145,10 +2184,10 @@ def summing_junction(inputs, output='y', dimension=None, name=None, prefix='u'):
2145
2184
2146
2185
Example
2147
2186
-------
2148
- >>> P = control.tf2io(ct.tf(1, [1, 0]), inputs ='u', outputs ='y')
2149
- >>> C = control.tf2io(ct.tf(10, [1, 1]), inputs ='e', outputs ='u')
2187
+ >>> P = control.tf2io(ct.tf(1, [1, 0]), input ='u', output ='y')
2188
+ >>> C = control.tf2io(ct.tf(10, [1, 1]), input ='e', output ='u')
2150
2189
>>> sumblk = control.summing_junction(inputs=['r', '-y'], output='e')
2151
- >>> T = control.interconnect((P, C, sumblk), inplist ='r', outlist ='y')
2190
+ >>> T = control.interconnect((P, C, sumblk), input ='r', output ='y')
2152
2191
2153
2192
"""
2154
2193
# Utility function to parse input and output signal lists
@@ -2181,6 +2220,16 @@ def _parse_list(signals, signame='input', prefix='u'):
2181
2220
# Return the parsed list
2182
2221
return nsignals , names , gains
2183
2222
2223
+ # Look for 'input' and 'output' parameter name variants
2224
+ inputs = _parse_signal_parameter (inputs , 'input' , kwargs )
2225
+ output = _parse_signal_parameter (output , 'outputs' , kwargs , end = True )
2226
+
2227
+ # Default values for inputs and output
2228
+ if inputs is None :
2229
+ raise TypeError ("input specification is required" )
2230
+ if output is None :
2231
+ output = 'y'
2232
+
2184
2233
# Read the input list
2185
2234
ninputs , input_names , input_gains = _parse_list (
2186
2235
inputs , signame = "input" , prefix = prefix )
0 commit comments