8000 append _linearize for system name + unit tests · python-control/python-control@e343a33 · GitHub
[go: up one dir, main page]

Skip to content

Commit e343a33

Browse files
committed
append _linearize for system name + unit tests
1 parent 4f08382 commit e343a33

File tree

2 files changed

+49
-11
lines changed

2 files changed

+49
-11
lines changed

control/iosys.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ def linearize(self, x0, u0, t=0, params={}, eps=1e-6,
551551
A[:, i] = (self._rhs(t, x0 + dx, u0) - F0) / eps
552552
C[:, i] = (self._out(t, x0 + dx, u0) - H0) / eps
553553

554-
# Perturb each of the input variables and compute linearization
554+
# Perturb each of the input variables and compute linearization
555555
for i in range(ninputs):
556556
du = np.zeros((ninputs,))
557557
du[i] = eps
@@ -565,6 +565,8 @@ def linearize(self, x0, u0, t=0, params={}, eps=1e-6,
565565

566566
# Set the names the system, inputs, outputs, and states
567567
if copy:
568+
if name is None:
569+
linsys.name = self.name + "_linearized"
568570
linsys.ninputs, linsys.input_index = self.ninputs, \
569571
self.input_index.copy()
570572
linsys.noutputs, linsys.output_index = \
@@ -1804,9 +1806,13 @@ def linearize(sys, xeq, ueq=[], t=0, params={}, **kw):
18041806
for the system as default values, overriding internal defaults.
18051807
copy : bool, Optional
18061808
If `copy` is True, copy the names of the input signals, output signals,
1807-
and states to the linearized system.
1809+
and states to the linearized system. If `name` is not specified,
1810+
the system name is set to the input system name with the string
1811+
'_linearized' appended.
18081812
name : string, optional
1809-
Set the name of the linearized system.
1813+
Set the name of the linearized system. If not specified and if `copy`
1814+
is `False`, a generic name <sys[id]> is generated with a unique
1815+
integer id.
18101816
18111817
Returns
18121818
-------

control/tests/iosys_test.py

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,22 @@ def test_nonlinear_iosys(self, tsys):
167167
np.testing.assert_array_almost_equal(lti_t, ios_t)
168168
np.testing.assert_allclose(lti_y, ios_y,atol=0.002,rtol=0.)
169169

170-
def test_linearize(self, tsys):
170+
@pytest.fixture
171+
def kincar(self):
172+
# Create a simple nonlinear system to check (kinematic car)
173+
def kincar_update(t, x, u, params):
174+
return np.array([np.cos(x[2]) * u[0], np.sin(x[2]) * u[0], u[1]])
175+
176+
def kincar_output(t, x, u, params):
177+
return np.array([x[0], x[1]])
178+
179+
return ios.NonlinearIOSystem(
180+
kincar_update, kincar_output,
181+
inputs = ['v', 'phi'],
182+
outputs = ['x', 'y'],
183+
states = ['x', 'y', 'theta'])
184+
185+
def test_linearize(self, tsys, kincar):
171186
# Create a single input/single output linear system
172187
linsys = tsys.siso_linsys
173188
iosys = ios.LinearIOSystem(linsys)
@@ -180,13 +195,7 @@ def test_linearize(self, tsys):
180195
np.testing.assert_array_almost_equal(linsys.D, linearized.D)
181196

182197
# Create a simple nonlinear system to check (kinematic car)
183-
def kincar_update(t, x, u, params):
184-
return np.array([np.cos(x[2]) * u[0], np.sin(x[2]) * u[0], u[1]])
185-
186-
def kincar_output(t, x, u, params):
187-
return np.array([x[0], x[1]])
188-
189-
iosys = ios.NonlinearIOSystem(kincar_update, kincar_output)
198+
iosys = kincar
190199
linearized = iosys.linearize([0, 0, 0], [0, 0])
191200
np.testing.assert_array_almost_equal(linearized.A, np.zeros((3,3)))
192201
np.testing.assert_array_almost_equal(
@@ -196,6 +205,29 @@ def kincar_output(t, x, u, params):
196205
np.testing.assert_array_almost_equal(linearized.D, np.zeros((2,2)))
197206

198207

208+
def test_linearize_named_signals(self, kincar):
209+
# Full form of the call
210+
linearized = kincar.linearize([0, 0, 0], [0, 0], copy=True,
211+
name='linearized')
212+
assert linearized.name == 'linearized'
213+
assert linearized.find_input('v') == 0
214+
assert linearized.find_input('phi') == 1
215+
assert linearized.find_output('x') == 0
216+
assert linearized.find_output('y') == 1
217+
assert linearized.find_state('x') == 0
218+
assert linearized.find_state('y') == 1
219+
assert linearized.find_state('theta') == 2
220+
221+
# If we copy signal names w/out a system name, append '_linearized'
222+
linearized = kincar.linearize([0, 0, 0], [0, 0], copy=True)
223+
assert linearized.name == kincar.name + '_linearized'
224+
225+
# If copy is False, signal names should not be copied
226+
lin_nocopy = kincar.linearize(0, 0, copy=False)
227+
assert lin_nocopy.find_input('v') is None
228+
assert lin_nocopy.find_output('x') is None
229+
assert lin_nocopy.find_state('x') is None
230+
199231
@noscipy0
200232
def test_connect(self, tsys):
201233
# Define a couple of (linear) systems to interconnection

0 commit comments

Comments
 (0)
0