diff --git a/control/iosys.py b/control/iosys.py index 78444f7c1..dca00d3e5 100644 --- a/control/iosys.py +++ b/control/iosys.py @@ -1862,7 +1862,7 @@ def ufun(t): return TimeResponseData( t_eval, y, None, u, issiso=sys.issiso(), - output_labels=sys.output_index, input_labels=sys.input_index, + output_labels=sys.output_labels, input_labels=sys.input_labels, transpose=transpose, return_x=return_x, squeeze=squeeze) # Create a lambda function for the right hand side @@ -1941,8 +1941,8 @@ def ivp_rhs(t, x): return TimeResponseData( soln.t, y, soln.y, u, issiso=sys.issiso(), - output_labels=sys.output_index, input_labels=sys.input_index, - state_labels=sys.state_index, + output_labels=sys.output_labels, input_labels=sys.input_labels, + state_labels=sys.state_labels, transpose=transpose, return_x=return_x, squeeze=squeeze) @@ -2881,7 +2881,7 @@ def interconnect( # Look for the signal name as a system input for sys in syslist: - if signal_name in sys.input_index.keys(): + if signal_name in sys.input_labels: connection.append(sign + sys.name + "." + signal_name) # Make sure we found the name diff --git a/control/statesp.py b/control/statesp.py index 41f92ae21..8661d8741 100644 --- a/control/statesp.py +++ b/control/statesp.py @@ -1777,7 +1777,9 @@ def _mimo2siso(sys, input, output, warn_conversion=False): new_B = sys.B[:, input] new_C = sys.C[output, :] new_D = sys.D[output, input] - sys = StateSpace(sys.A, new_B, new_C, new_D, sys.dt) + sys = StateSpace(sys.A, new_B, new_C, new_D, sys.dt, + name=sys.name, + inputs=sys.input_labels[input], outputs=sys.output_labels[output]) return sys @@ -1826,7 +1828,9 @@ def _mimo2simo(sys, input, warn_conversion=False): # Y = C*X + D*U new_B = sys.B[:, input:input+1] new_D = sys.D[:, input:input+1] - sys = StateSpace(sys.A, new_B, sys.C, new_D, sys.dt) + sys = StateSpace(sys.A, new_B, sys.C, new_D, sys.dt, + name=sys.name, + inputs=sys.input_labels[input], outputs=sys.output_labels) return sys diff --git a/control/tests/trdata_test.py b/control/tests/trdata_test.py index 734d35599..028e53580 100644 --- a/control/tests/trdata_test.py +++ b/control/tests/trdata_test.py @@ -196,15 +196,20 @@ def test_response_copy(): with pytest.raises(ValueError, match="not enough"): t, y, x = response_mimo - # Labels - assert response_mimo.output_labels is None - assert response_mimo.state_labels is None - assert response_mimo.input_labels is None + # Make sure labels are transferred to the response + assert response_siso.output_labels == sys_siso.output_labels + assert response_siso.state_labels == sys_siso.state_labels + assert response_siso.input_labels == sys_siso.input_labels + assert response_mimo.output_labels == sys_mimo.output_labels + assert response_mimo.state_labels == sys_mimo.state_labels + assert response_mimo.input_labels == sys_mimo.input_labels + + # Check relabelling response = response_mimo( output_labels=['y1', 'y2'], input_labels='u', - state_labels=["x[%d]" % i for i in range(4)]) + state_labels=["x%d" % i for i in range(4)]) assert response.output_labels == ['y1', 'y2'] - assert response.state_labels == ['x[0]', 'x[1]', 'x[2]', 'x[3]'] + assert response.state_labels == ['x0', 'x1', 'x2', 'x3'] assert response.input_labels == ['u'] # Unknown keyword @@ -231,6 +236,17 @@ def test_trdata_labels(): np.testing.assert_equal( response.input_labels, ["u[%d]" % i for i in range(sys.ninputs)]) + # Make sure the selected input and output are both correctly transferred to the response + for nu in range(sys.ninputs): + for ny in range(sys.noutputs): + step_response = ct.step_response(sys, T, input=nu, output=ny) + assert step_response.input_labels == [sys.input_labels[nu]] + assert step_response.output_labels == [sys.output_labels[ny]] + + init_response = ct.initial_response(sys, T, input=nu, output=ny) + assert init_response.input_labels == None + assert init_response.output_labels == [sys.output_labels[ny]] + def test_trdata_multitrace(): # diff --git a/control/timeresp.py b/control/timeresp.py index 638a07329..bd8595cfe 100644 --- a/control/timeresp.py +++ b/control/timeresp.py @@ -694,7 +694,10 @@ def _process_labels(labels, signal, length): raise ValueError("Name dictionary for %s is incomplete" % signal) # Convert labels to a list - labels = list(labels) + if isinstance(labels, str): + labels = [labels] + else: + labels = list(labels) # Make sure the signal list is the right length and type if len(labels) != length: @@ -1111,6 +1114,8 @@ def forced_response(sys, T=None, U=0., X0=0., transpose=False, return TimeResponseData( tout, yout, xout, U, issiso=sys.issiso(), + output_labels=sys.output_labels, input_labels=sys.input_labels, + state_labels=sys.state_labels, transpose=transpose, return_x=return_x, squeeze=squeeze) @@ -1374,8 +1379,16 @@ def step_response(sys, T=None, X0=0., input=None, output=None, T_num=None, # Figure out if the system is SISO or not issiso = sys.issiso() or (input is not None and output is not None) + # Select only the given input and output, if any + input_labels = sys.input_labels if input is None \ + else sys.input_labels[input] + output_labels = sys.output_labels if output is None \ + else sys.output_labels[output] + return TimeResponseData( response.time, yout, xout, uout, issiso=issiso, + output_labels=output_labels, input_labels=input_labels, + state_labels=sys.state_labels, transpose=transpose, return_x=return_x, squeeze=squeeze) @@ -1704,9 +1717,15 @@ def initial_response(sys, T=None, X0=0., input=0, output=None, T_num=None, # Figure out if the system is SISO or not issiso = sys.issiso() or (input is not None and output is not None) + # Select only the given output, if any + output_labels = sys.output_labels if output is None \ + else sys.output_labels[0] + # Store the response without an input return TimeResponseData( response.t, response.y, response.x, None, issiso=issiso, + output_labels=output_labels, input_labels=None, + state_labels=sys.state_labels, transpose=transpose, return_x=return_x, squeeze=squeeze) @@ -1798,7 +1817,7 @@ def impulse_response(sys, T=None, X0=0., input=None, output=None, T_num=None, ----- This function uses the `forced_response` function to compute the time response. For continuous time systems, the initial condition is altered to - account for the initial impulse. For discrete-time aystems, the impulse is + account for the initial impulse. For discrete-time aystems, the impulse is sized so that it has unit area. Examples @@ -1869,8 +1888,16 @@ def impulse_response(sys, T=None, X0=0., input=None, output=None, T_num=None, # Figure out if the system is SISO or not issiso = sys.issiso() or (input is not None and output is not None) + # Select only the given input and output, if any + input_labels = sys.input_labels if input is None \ + else sys.input_labels[input] + output_labels = sys.output_labels if output is None \ + else sys.output_labels[output] + return TimeResponseData( response.time, yout, xout, uout, issiso=issiso, + output_labels=output_labels, input_labels=input_labels, + state_labels=sys.state_labels, transpose=transpose, return_x=return_x, squeeze=squeeze) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy