Repository navigation
Fixed InterconnectedSystems name bugs. #400
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
672f229
15a442a
77f9441
d45a6c0
b688729
c8fba97
bd38dea
35676f2
90705d4
69cc8c5
e76a4f8
abb1f19
f955b3a
3ec2f02
8c957b2
b2c8d44
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -76,7 +76,8 @@ class for a set of subclasses that are used to implement specific | |
| Parameter values for the systems. Passed to the evaluation functions | ||
| for the system as default values, overriding internal defaults. | ||
| name : string, optional | ||
| System name (used for specifying signals) | ||
| System name (used for specifying signals). If unspecified, a generic | ||
| name <sys[id]> is generated with a unique integer id. | ||
|
|
||
| Attributes | ||
| ---------- | ||
|
|
@@ -540,10 +541,10 @@ def linearize(self, x0, u0, t=0, params={}, eps=1e-6): | |
| linsys = StateSpace(A, B, C, D, self.dt, remove_useless=False) | ||
| return LinearIOSystem(linsys) | ||
|
|
||
| def copy(self): | ||
| def copy(self, newname=None): | ||
| """Make a copy of an input/output system.""" | ||
| newsys = copy.copy(self) | ||
| newsys.name = self.name_or_default(None) | ||
| newsys.name = self.name_or_default(newname) | ||
| return newsys | ||
|
|
||
|
|
||
|
|
@@ -588,7 +589,8 @@ def __init__(self, linsys, inputs=None, outputs=None, states=None, | |
| functions for the system as default values, overriding internal | ||
| defaults. | ||
| name : string, optional | ||
| System name (used for specifying signals) | ||
| System name (used for specifying signals). If unspecified, a generic | ||
| name <sys[id]> is generated with a unique integer id. | ||
|
|
||
| Returns | ||
| ------- | ||
|
|
@@ -706,7 +708,8 @@ def __init__(self, updfcn, outfcn=None, inputs=None, outputs=None, | |
| * dt = True Discrete time with unspecified sampling time | ||
|
|
||
| name : string, optional | ||
| System name (used for specifying signals). | ||
| System name (used for specifying signals). If unspecified, a generic | ||
| name <sys[id]> is generated with a unique integer id. | ||
|
|
||
| Returns | ||
| ------- | ||
|
|
@@ -841,6 +844,23 @@ def __init__(self, syslist, connections=[], inplist=[], outlist=[], | |
| If omitted, the output map can be specified using the | ||
| `set_output_map` method. | ||
|
|
||
| inputs : int, list of str or None, optional | ||
| Description of the system inputs. This can be given as an integer | ||
| count or as a list of strings that name the individual signals. | ||
| If an integer count is specified, the names of the signal will be | ||
| of the form `s[i]` (where `s` is one of `u`, `y`, or `x`). If | ||
| this parameter is not given or given as `None`, the relevant | ||
| quantity will be determined when possible based on other | ||
| information provided to functions using the system. | ||
|
|
||
| outputs : int, list of str or None, optional | ||
| Description of the system outputs. Same format as `inputs`. | ||
|
|
||
| states : int, list of str, or None, optional | ||
| Description of the system states. Same format as `inputs`, except | ||
| the state names will be of the form '<subsys_name>.<state_name>', | ||
| for each subsys in syslist and each state_name of each subsys. | ||
|
|
||
| params : dict, optional | ||
| Parameter values for the systems. Passed to the evaluation | ||
| functions for the system as default values, overriding internal | ||
|
|
@@ -857,7 +877,8 @@ def __init__(self, syslist, connections=[], inplist=[], outlist=[], | |
| * dt = True Discrete time with unspecified sampling time | ||
|
|
||
| name : string, optional | ||
| System name (used for specifying signals). | ||
| System name (used for specifying signals). If unspecified, a generic | ||
| name <sys[id]> is generated with a unique integer id. | ||
|
|
||
| """ | ||
| # Convert input and output names to lists if they aren't already | ||
|
|
@@ -904,24 +925,29 @@ def __init__(self, syslist, connections=[], inplist=[], outlist=[], | |
| system_count += 1 | ||
|
samlaf marked this conversation as resolved.
Resolved
|
||
|
|
||
| # Check for duplicate systems or duplicate names | ||
| sysobj_list = [] | ||
| sysname_list = [] | ||
| # Duplicates are renamed sysname_1, sysname_2, etc. | ||
| sysobj_name_dct = {} | ||
| sysname_count_dct = {} | ||
| for sys in syslist: | ||
| if sys in sysobj_list: | ||
| warn("Duplicate object found in system list: %s" % str(sys)) | ||
| elif sys.name is not None and sys.name in sysname_list: | ||
| warn("Duplicate name found in system list: %s" % sys.name) | ||
| if sys in sysobj_name_dct: | ||
| raise ValueError("Duplicate object found in system list: %s" % str(sys)) | ||
| elif sys.name is not None and sys.name in sysname_count_dct: | ||
| count = sysname_count_dct[sys.name] | ||
| sysname_count_dct[sys.name] += 1 | ||
| sysname = sys.name + "_" + str(count) | ||
| sysobj_name_dct[sys] = sysname | ||
| warn("Duplicate name found in system list. Renamed to {}".format(sysname)) | ||
| else: | ||
| sysname_count_dct[sys.name] = 1 | ||
| sysobj_name_dct[sys] = sys.name | ||
|
|
||
| sysobj_list.append(sys) | ||
| sysname_list.append(sys.name) | ||
|
|
||
| # This won't work when there are duplicate sysnames | ||
| # Should we throw an error rather than just warning above? | ||
| # Users can use sys.copy() to get a unique name for the dup system. | ||
| if states is None: | ||
| states = [] | ||
| for sys in sysobj_list: | ||
| states += [sys.name + '.' + statename for statename in sys.state_index.keys()] | ||
| for sys, name in sysobj_name_dct.items(): | ||
| states += [name + '.' + statename for statename in sys.state_index.keys()] | ||
|
|
||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @murrayrm This is the part that would break if you add a named signal with a generic 'sys[i]' that will cause a conflict (it's no different from having two systems with the same name). The only "bad" thing that happens is that the system will be missing the state names of the systems with conflicting names (only the first 'sys[i].states' will be present). Edit: see the comment above this snippet of code... I'm new to this and not sure how to include it in the comment. |
||
| # Create the I/O system | ||
| super(InterconnectedSystem, self).__init__( | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.