Skip to content

Commit b29233e

Browse files
committed
add __str__ for I/O systems + additional signal name fixes
1 parent 7be744c commit b29233e

File tree

1 file changed

+40
-23
lines changed

1 file changed

+40
-23
lines changed

control/iosys.py

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,17 @@ def __init__(self, inputs=None, outputs=None, states=None, params={},
210210
def __repr__(self):
211211
return self.name if self.name is not None else str(type(self))
212212

213+
def __str__(self):
214+
"""String representation of an input/output system"""
215+
str = "System: " + (self.name if self.name else "(none)") + "\n"
216+
str += "Inputs (%d): " % self.ninputs
217+
for key in self.input_index: str += key + ", "
218+
str += "\nOutputs (%d): " % self.noutputs
219+
for key in self.output_index: str += key + ", "
220+
str += "\nStates (%d): " % self.nstates
221+
for key in self.state_index: str += key + ", "
222+
return str
223+
213224
def __mul__(sys2, sys1):
214225
"""Multiply two input/output systems (series interconnection)"""
215226

@@ -437,7 +448,7 @@ def set_outputs(self, outputs, prefix='y'):
437448
optional prefix parameter).
438449
prefix : string, optional
439450
If `outputs` is an integer, create the names of the states using
440-
the given prefix (default = 'u'). The names of the input will be
451+
the given prefix (default = 'y'). The names of the input will be
441452
of the form `prefix[i]`.
442453
443454
"""
@@ -457,7 +468,7 @@ def set_states(self, states, prefix='x'):
457468
optional prefix parameter).
458469
prefix : string, optional
459470
If `states` is an integer, create the names of the states using
460-
the given prefix (default = 'u'). The names of the input will be
471+
the given prefix (default = 'x'). The names of the input will be
461472
of the form `prefix[i]`.
462473
463474
"""
@@ -671,13 +682,16 @@ def __init__(self, linsys, inputs=None, outputs=None, states=None,
671682

672683
# Process input, output, state lists, if given
673684
# Make sure they match the size of the linear system
674-
ninputs, self.input_index = self._process_signal_list(inputs)
685+
ninputs, self.input_index = self._process_signal_list(
686+
inputs if inputs is not None else linsys.inputs, prefix='u')
675687
if ninputs is not None and linsys.inputs != ninputs:
676688
raise ValueError("Wrong number/type of inputs given.")
677-
noutputs, self.output_index = self._process_signal_list(outputs)
689+
noutputs, self.output_index = self._process_signal_list(
690+
outputs if outputs is not None else linsys.outputs, prefix='y')
678691
if noutputs is not None and linsys.outputs != noutputs:
679692
raise ValueError("Wrong number/type of outputs given.")
680-
nstates, self.state_index = self._process_signal_list(states)
693+
nstates, self.state_index = self._process_signal_list(
694+
states if states is not None else linsys.states, prefix='x')
681695
if nstates is not None and linsys.states != nstates:
682696
raise ValueError("Wrong number/type of states given.")
683697

@@ -872,20 +886,20 @@ def __init__(self, syslist, connections=[], inplist=[], outlist=[],
872886
873887
inplist : tuple of input specifications, optional
874888
List of specifications for how the inputs for the overall system
875-
are mapped to the subsystems. The input specification is the same
876-
as the form defined in the connection specification. Each system
877-
input is added to the input for the listed subsystem.
889+
are mapped to the subsystem inputs. The input specification is
890+
the same as the form defined in the connection specification.
891+
Each system input is added to the input for the listed subsystem.
878892
879893
If omitted, the input map can be specified using the
880894
`set_input_map` method.
881895
882896
outlist : tuple of output specifications, optional
883897
List of specifications for how the outputs for the subsystems are
884-
mapped to overall system. The output specification is the same as
885-
the form defined in the connection specification (including the
886-
optional gain term). Numbered outputs must be chosen from the
887-
list of subsystem outputs, but named outputs can also be contained
888-
in the list of subsystem inputs.
898+
mapped to overall system outputs. The output specification is the
899+
same as the form defined in the connection specification
900+
(including the optional gain term). Numbered outputs must be
901+
chosen from the list of subsystem outputs, but named outputs can
902+
also be contained in the list of subsystem inputs.
889903
890904
If omitted, the output map can be specified using the
891905
`set_output_map` method.
@@ -968,10 +982,12 @@ def __init__(self, syslist, connections=[], inplist=[], outlist=[],
968982
states=nstates, params=params, dt=dt)
969983

970984
# If input or output list was specified, update it
971-
nsignals, self.input_index = self._process_signal_list(inputs)
985+
nsignals, self.input_index = \
986+
self._process_signal_list(inputs, prefix='u')
972987
if nsignals is not None and len(inplist) != nsignals:
973988
raise ValueError("Wrong number/type of inputs given.")
974-
nsignals, self.output_index = self._process_signal_list(outputs)
989+
nsignals, self.output_index = \
990+
self._process_signal_list(outputs, prefix='y')
975991
if nsignals is not None and len(outlist) != nsignals:
976992
raise ValueError("Wrong number/type of outputs given.")
977993

@@ -985,8 +1001,10 @@ def __init__(self, syslist, connections=[], inplist=[], outlist=[],
9851001

9861002
# Convert the input list to a matrix: maps system to subsystems
9871003
self.input_map = np.zeros((ninputs, self.ninputs))
988-
for index in range(len(inplist)):
989-
self.input_map[self._parse_input_spec(inplist[index]), index] = 1
1004+
for index, inpspec in enumerate(inplist):
1005+
if isinstance(inpspec, (int, str, tuple)): inpspec = [inpspec]
1006+
for spec in inpspec:
1007+
self.input_map[self._parse_input_spec(spec), index] = 1
9901008

9911009
# Convert the output list to a matrix: maps subsystems to system
9921010
self.output_map = np.zeros((self.noutputs, noutputs + ninputs))
@@ -1120,10 +1138,9 @@ def _compute_static_io(self, t, x, u):
11201138
def _parse_input_spec(self, spec):
11211139
"""Parse an input specification and returns the index
11221140
1123-
This function parses a specification of an input of an
1124-
interconnected system component and returns the index of that
1125-
input in the internal input vector. Input specifications
1126-
are of one of the following forms:
1141+
This function parses a specification of an input of an interconnected
1142+
system component and returns the index of that input in the internal
1143+
input vector. Input specifications are of one of the following forms:
11271144
11281145
i first input for the ith system
11291146
(i,) first input for the ith system
@@ -1232,8 +1249,8 @@ def _parse_signal(self, spec, signame='input', dictname=None):
12321249
# For now, only allow signal level of system name
12331250
# TODO: expand to allow nested signal names
12341251
if len(namelist) != 2:
1235-
raise ValueError("Couldn't parse signal reference '%s'."
1236-
% spec)
1252+
raise ValueError("Couldn't parse %s signal reference '%s'."
1253+
% (signame, spec))
12371254

12381255
system_index = self._find_system(namelist[0])
12391256
if system_index is None:

0 commit comments

Comments
 (0)