8000 Merge pull request #892 from joaoantoniocardoso/patch-2 · python-control/python-control@147d531 · GitHub
[go: up one dir, main page]

Skip to content

Commit 147d531

Browse files
authored
Merge pull request #892 from joaoantoniocardoso/patch-2
Add missing labels when returning TimeResponseData
2 parents 9c26e22 + bd83e8c commit 147d531

File tree

4 files changed

+61
-14
lines changed

4 files changed

+61
-14
lines changed

control/iosys.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1862,7 +1862,7 @@ def ufun(t):
18621862

18631863
return TimeResponseData(
18641864
t_eval, y, None, u, issiso=sys.issiso(),
1865-
output_labels=sys.output_index, input_labels=sys.input_index,
1865+
output_labels=sys.output_labels, input_labels=sys.input_labels,
18661866
transpose=transpose, return_x=return_x, squeeze=squeeze)
18671867

18681868
# Create a lambda function for the right hand side
@@ -1941,8 +1941,8 @@ def ivp_rhs(t, x):
19411941

19421942
return TimeResponseData(
19431943
soln.t, y, soln.y, u, issiso=sys.issiso(),
1944-
output_labels=sys.output_index, input_labels=sys.input_index,
1945-
state_labels=sys.state_index,
1944+
output_labels=sys.output_labels, input_labels=sys.input_labels,
1945+
state_labels=sys.state_labels,
19461946
transpose=transpose, return_x=return_x, squeeze=squeeze)
19471947

19481948

@@ -2881,7 +2881,7 @@ def interconnect(
28812881

28822882
# Look for the signal name as a system input
28832883
for sys in syslist:
2884-
if signal_name in sys.input_index.keys():
2884+
if signal_name in sys.input_labels:
28852885
connection.append(sign + sys.name + "." + signal_name)
28862886

28872887
# Make sure we found the name

control/statesp.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1777,7 +1777,9 @@ def _mimo2siso(sys, input, output, warn_conversion=False):
17771777
new_B = sys.B[:, input]
17781778
new_C = sys.C[output, :]
17791779
new_D = sys.D[output, input]
1780-
sys = StateSpace(sys.A, new_B, new_C, new_D, sys.dt)
1780+
sys = StateSpace(sys.A, new_B, new_C, new_D, sys.dt,
1781+
name=sys.name,
1782+
inputs=sys.input_labels[input], outputs=sys.output_labels[output])
17811783

17821784
return sys
17831785

@@ -1826,7 +1828,9 @@ def _mimo2simo(sys, input, warn_conversion=False):
18261828
# Y = C*X + D*U
18271829
new_B = sys.B[:, input:input+1]
18281830
new_D = sys.D[:, input:input+1]
1829-
sys = StateSpace(sys.A, new_B, sys.C, new_D, sys.dt)
1831+
sys = StateSpace(sys.A, new_B, sys.C, new_D, sys.dt,
1832+
name=sys.name,
1833+
inputs=sys.input_labels[input], outputs=sys.output_labels)
18301834

18311835
return sys
18321836

control/tests/trdata_test.py

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -196,15 +196,20 @@ def test_response_copy():
196196
with pytest.raises(ValueError, match="not enough"):
197197
t, y, x = response_mimo
198198

199-
# Labels
200-
assert response_mimo.output_labels is None
201-
assert response_mimo.state_labels is None
202-
assert response_mimo.input_labels is None
199+
# Make sure labels are transferred to the response
200+
assert response_siso.output_labels == sys_siso.output_labels
201+
assert response_siso.state_labels == sys_siso.state_labels
202+
assert response_siso.input_labels == sys_siso.input_labels
203+
assert response_mimo.output_labels == sys_mimo.output_labels
204+
assert response_mimo.state_labels == sys_mimo.state_labels
205+
assert response_mimo.input_labels == sys_mimo.input_labels
206+
207+
# Check relabelling
203208
response = response_mimo(
204209
output_labels=['y1', 'y2'], input_labels='u',
205-
state_labels=["x[%d]" % i for i in range(4)])
210+
state_labels=["x%d" % i for i in range(4)])
206211
assert response.output_labels == ['y1', 'y2']
207-
assert response.state_labels == ['x[0]', 'x[1]', 'x[2]', 'x[3]']
212+
assert response.state_labels == ['x0', 'x1', 'x2', 'x3']
208213
assert response.input_labels == ['u']
209214

210215
# Unknown keyword
@@ -231,6 +236,17 @@ def test_trdata_labels():
231236
np.testing.assert_equal(
232237
response.input_labels, ["u[%d]" % i for i in range(sys.ninputs)])
233238

239+
# Make sure the selected input and output are both correctly transferred to the response
240+
for nu in range(sys.ninputs):
241+
for ny in range(sys.noutputs):
242+
step_response = ct.step_response(sys, T, input=nu, output=ny)
243+
assert step_response.input_labels == [sys.input_labels[nu]]
244+
assert step_response.output_labels == [sys.output_labels[ny]]
245+
246+
init_response = ct.initial_response(sys, T, input=nu, output=ny)
247+
assert init_response.input_labels == None
248+
assert init_response.output_labels == [sys.output_labels[ny]]
249+
234250

235251
def test_trdata_multitrace():
236252
#

control/timeresp.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,10 @@ def _process_labels(labels, signal, length):
694694
raise ValueError("Name dictionary for %s is incomplete" % signal)
695695

696696
# Convert labels to a list
697-
labels = list(labels)
697+
if isinstance(labels, str):
698+
labels = [labels]
699+
else:
700+
labels = list(labels)
698701

699702
# Make sure the signal list is the right length and type
700703
if len(labels) != length:
@@ -1111,6 +1114,8 @@ def forced_response(sys, T=None, U=0., X0=0., transpose=False,
11111114

11121115
return TimeResponseData(
11131116
tout, yout, xout, U, issiso=sys.issiso(),
1117+
output_labels=sys.output_labels, input_labels=sys.input_labels,
1118+
state_labels=sys.state_labels,
11141119
transpose=transpose, return_x=return_x, squeeze=squeeze)
11151120

11161121

@@ -1374,8 +1379,16 @@ def step_response(sys, T=None, X0=0., input=None, output=None, T_num=None,
13741379
# Figure out if the system is SISO or not
13751380
issiso = sys.issiso() or (input is not None and output is not None)
13761381

1382+
# Select only the given input and output, if any
1383+
input_labels = sys.input_labels if input is None \
1384+
else sys.input_labels[input]
1385+
output_labels = sys.output_labels if output is None \
1386+
else sys.output_labels[output]
1387+
13771388
return TimeResponseData(
13781389
response.time, yout, xout, uout, issiso=issiso,
1390+
output_labels=output_labels, input_labels=input_labels,
1391+
state_labels=sys.state_labels,
13791392
transpose=transpose, return_x=return_x, squeeze=squeeze)
13801393

13811394

@@ -1704,9 +1717,15 @@ def initial_response(sys, T=None, X0=0., input=0, output=None, T_num=None,
17041717
# Figure out if the system is SISO or not
17051718
issiso = sys.issiso() or (input is not None and output is not None)
17061719

1720+
# Select only the given output, if any
1721+
output_labels = sys.output_labels if output is None \
1722+
else sys.output_labels[0]
1723+
17071724
# Store the response without an input
17081725
return TimeResponseData(
17091726
response.t, response.y, response.x, None, issiso=issiso,
1727+
output_labels=output_labels, input_labels=None,
1728+
state_labels=sys.state_labels,
17101729
transpose=transpose, return_x=return_x, squeeze=squeeze)
17111730

17121731

@@ -1798,7 +1817,7 @@ def impulse_response(sys, T=None, X0=0., input=None, output=None, T_num=None,
17981817
-----
17991818
This function uses the `forced_response` function to compute the time
18001819
response. For continuous time systems, the initial condition is altered to
1801-
account for the initial impulse. For discrete-time aystems, the impulse is
1820+
account for the initial impulse. For discrete-time aystems, the impulse is
18021821
sized so that it has unit area.
18031822
18041823
Examples
@@ -1869,8 +1888,16 @@ def impulse_response(sys, T=None, X0=0., input=None, output=None, T_num=None,
18691888
# Figure out if the system is SISO or not
18701889
issiso = sys.issiso() or (input is not None and output is not None)
18711890

1891+
# Select only the given input and output, if any
1892+
input_labels = sys.input_labels if input is None \
1893+
else sys.input_labels[input]
1894+
output_labels = sys.output_labels if output is None \
1895+
else sys.output_labels[output]
1896+
18721897
return TimeResponseData(
18731898
response.time, yout, xout, uout, issiso=issiso,
1899+
output_labels=output_labels, input_labels=input_labels,
1900+
s 479D tate_labels=sys.state_labels,
18741901
transpose=transpose, return_x=return_x, squeeze=squeeze)
18751902

18761903

0 commit comments

Comments
 (0)
0