Skip to content

Commit 2e872f8

Browse files
committed
fix interconnect() issue #1015
1 parent e5394c4 commit 2e872f8

File tree

2 files changed

+59
-14
lines changed

2 files changed

+59
-14
lines changed

control/nlsys.py

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2219,7 +2219,7 @@ def interconnect(
22192219
... inplist=['C'], outlist=['P'])
22202220
22212221
A feedback system can also be constructed using the
2222-
:func:`~control.summing_block` function and the ability to
2222+
:func:`~control.summing_junction` function and the ability to
22232223
automatically interconnect signals with the same names:
22242224
22252225
>>> P = ct.tf(1, [1, 0], inputs='u', outputs='y')
@@ -2425,15 +2425,22 @@ def interconnect(
24252425
elif not found_system:
24262426
raise ValueError("could not find signal %s" % sname)
24272427
else:
2428-
# Regular signal specification
2429-
if not isinstance(connection, list):
2430-
dprint(f" converting item to list")
2431-
connection = [connection]
2432-
for spec in connection:
2433-
isys, indices, gain = _parse_spec(syslist, spec, 'input')
2428+
# TODO: refactor code to remove duplication
2429+
if isinstance(connection, list):
2430+
# Passed a list => create input map
2431+
dprint(f" detected input list")
2432+
new_inplist.append([])
2433+
for spec in connection:
2434+
isys, indices, gain = _parse_spec(syslist, spec, 'input')
2435+
for isig in indices:
2436+
new_inplist[-1].append((isys, isig, gain))
2437+
dprint(f" adding input {(isys, isig, gain)}")
2438+
else:
2439+
# Passed a single single => single input
2440+
isys, indices, gain = _parse_spec(syslist, connection, 'input')
24342441
for isig in indices:
2435-
dprint(f" adding input {(isys, isig, gain)}")
24362442
new_inplist.append((isys, isig, gain))
2443+
dprint(f" adding input {(isys, isig, gain)}")
24372444
inplist, inputs = new_inplist, new_inputs
24382445
dprint(f" {inplist=}\n {inputs=}")
24392446

@@ -2499,14 +2506,36 @@ def interconnect(
24992506
elif not found_system:
25002507
raise ValueError("could not find signal %s" % sname)
25012508
else:
2502-
# Regular signal specification
2503-
if not isinstance(connection, list):
2504-
dprint(f" converting item to list")
2505-
connection = [connection]
2506-
for spec in connection:
2509+
# TODO: refactor code to remove duplication
2510+
if isinstance(connection, list):
2511+
# Passed a list => create input map
2512+
dprint(f" detected output list")
2513+
new_outlist.append([])
2514+
for spec in connection:
2515+
try:
2516+
# First trying looking in the output signals
2517+
osys, indices, gain = _parse_spec(
2518+
syslist, spec, 'output')
2519+
for osig in indices:
2520+
dprint(f" adding output {(osys, osig, gain)}")
2521+
new_outlist[-1].append((osys, osig, gain))
2522+
except ValueError:
2523+
# If not, see if we can find it in inputs
2524+
isys, indices, gain = _parse_spec(
2525+
syslist, spec, 'input or output',
2526+
dictname='input_index')
2527+
for isig in indices:
2528+
# Use string form to allow searching input list
2529+
dprint(f" adding input {(isys, isig, gain)}")
2530+
new_outlist[-1].append(
2531+
(syslist[isys].name,
2532+
syslist[isys].input_labels[isig], gain))
2533+
else:
2534+
spec = connection
25072535
try:
25082536
# First trying looking in the output signals
2509-
osys, indices, gain = _parse_spec(syslist, spec, 'output')
2537+
osys, indices, gain = _parse_spec(
2538+
syslist, spec, 'output')
25102539
for osig in indices:
25112540
dprint(f" adding output {(osys, osig, gain)}")
25122541
new_outlist.append((osys, osig, gain))

control/tests/interconnect_test.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,3 +689,19 @@ def test_interconnect_params():
689689
timepts = np.linspace(0, 10)
690690
resp = ct.input_output_response(sys, timepts, 0, params={'a': -1})
691691
assert resp.states[0, -1].item() < 2 * math.exp(-10)
692+
693+
694+
# Bug identified in issue #1015
695+
def test_parallel_interconnect():
696+
sys1 = ct.rss(2, 1, 1, name='S1')
697+
sys2 = ct.rss(2, 1, 1, name='S2')
698+
699+
sys_bd = sys1 + sys2
700+
sys_ic = ct.interconnect(
701+
[sys1, sys2],
702+
inplist=[['S1.u[0]', 'S2.u[0]']],
703+
outlist=[['S1.y[0]', 'S2.y[0]']])
704+
np.testing.assert_allclose(sys_bd.A, sys_ic.A)
705+
np.testing.assert_allclose(sys_bd.B, sys_ic.B)
706+
np.testing.assert_allclose(sys_bd.C, sys_ic.C)
707+
np.testing.assert_allclose(sys_bd.D, sys_ic.D)

0 commit comments

Comments
 (0)