Skip to content

Commit e24c7de

Browse files
committed
Fixups following review
control/robust.py: - doc-strings conform to python-control conventions - use plain tuple instead of namedtuple for auxiliary output in mixsyn control/statesp.py: - don't import pi from numpy - doc-string for _matrix expanded, conforms to conventions control/tests/robust_test.py - change test to accept plain tuple
1 parent 7b883ef commit e24c7de

File tree

3 files changed

+78
-25
lines changed

3 files changed

+78
-25
lines changed

control/robust.py

Lines changed: 62 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,32 @@ def hinfsyn(P,nmeas,ncon):
173173
return K, CL, gam, rcond
174174

175175

176-
def _size_as_needed(w,wname,n):
177-
"""_size_as_needed(w,wname,n) -> w2
178-
If w is scalar, reshape to nxn; otherwise check size is OK. Return w as StateSpace object.
179-
If w is None, return empty StateSpace object.
176+
def _size_as_needed(w, wname, n):
177+
"""Convert LTI object to appropriately sized StateSpace object.
178+
179+
Intended for use in .robust only
180+
181+
Parameters
182+
----------
183+
w: None, 1x1 LTI object, or mxn LTI object
184+
wname: name of w, for error message
185+
n: number of inputs to w
186+
187+
Returns
188+
-------
189+
w_: processed weighting function, a StateSpace object:
190+
- if w is None, empty StateSpace object
191+
- if w is scalar, w_ will be w * eye(n)
192+
- otherwise, w as StateSpace object
193+
194+
Raises
195+
------
196+
ValueError
197+
- if w is not None or scalar, and doesn't have n inputs
198+
199+
See Also
200+
--------
201+
augw
180202
"""
181203
from . import append, ss
182204
if w is not None:
@@ -195,20 +217,36 @@ def _size_as_needed(w,wname,n):
195217

196218

197219
def augw(g,w1=None,w2=None,w3=None):
198-
"""augw(g,w1=None,w2=None,w3=None) -> p
199-
Augment plant for mixed sensitivity problem
200-
g - LTI object, ny-by-nu
201-
w1 - weighting on S; None, scalar, or k1-by-ny LTI object
202-
w2 - weighting on KS; None, scalar, or k2-by-nu LTI object
203-
w3 - weighting on T; None, scalar, or k3-by-ny LTI object
204-
p - augmented plant; StateSpace object
220+
"""Augment plant for mixed sensitivity problem.
221+
222+
Parameters
223+
----------
224+
g: LTI object, ny-by-nu
225+
w1: weighting on S; None, scalar, or k1-by-ny LTI object
226+
w2: weighting on KS; None, scalar, or k2-by-nu LTI object
227+
w3: weighting on T; None, scalar, or k3-by-ny LTI object
228+
p: augmented plant; StateSpace object
229+
205230
If a weighting is None, no augmentation is done for it. At least
206231
one weighting must not be None.
232+
207233
If a weighting w is scalar, it will be replaced by I*w, where I is
208234
ny-by-ny for w1 and w3, and nu-by-nu for w2.
209235
210-
See also hinfsyn, mixsyn
236+
Returns
237+
-------
238+
p: plant augmented with weightings, suitable for submission to hinfsyn or h2syn.
239+
240+
Raises
241+
------
242+
ValueError
243+
- if all weightings are None
244+
245+
See Also
246+
--------
247+
h2syn, hinfsyn, mixsyn
211248
"""
249+
212250
from . import append, ss, connect
213251

214252
if w1 is None and w2 is None and w3 is None:
@@ -282,22 +320,27 @@ def augw(g,w1=None,w2=None,w3=None):
282320

283321
return p
284322

285-
from collections import namedtuple as _namedtuple
286-
_mixsyn_info = _namedtuple('mixsyn_info',('gamma','rcond'))
287-
288323
def mixsyn(g,w1=None,w2=None,w3=None):
289-
"""mixsyn(g,w1,w2,w3) -> k,cl,info
290-
Mixed-sensitivity H-infinity synthesis
324+
"""Mixed-sensitivity H-infinity synthesis.
325+
326+
mixsyn(g,w1,w2,w3) -> k,cl,info
327+
328+
Parameters
329+
----------
291330
g: LTI; the plant for which controller must be synthesized
292331
w1: weighting on s = (1+g*k)**-1; None, or scalar or k1-by-ny LTI
293332
w2: weighting on k*s; None, or scalar or k2-by-nu LTI
294333
w3: weighting on t = g*k*(1+g*k)**-1; None, or scalar or k3-by-ny LTI
295334
At least one of w1, w2, and w3 must not be None.
335+
336+
Returns
337+
-------
296338
k: synthesized controller; StateSpace object
297339
cl: closed system mapping evaluation inputs to evaluation outputs; if p is the augmented plant, with
298340
[z] = [p11 p12] [w], then cl is the system from w->z with u=-k*y. StateSpace object.
299341
[y] [p21 g] [u]
300-
info: namedtuple with fields, in order,
342+
343+
info: tuple with entries, in order,
301344
gamma: scalar; H-infinity norm of cl
302345
rcond: array; estimates of reciprocal condition numbers
303346
computed during synthesis. See hinfsyn for details
@@ -312,5 +355,5 @@ def mixsyn(g,w1=None,w2=None,w3=None):
312355
p = augw(g,w1,w2,w3)
313356

314357
k,cl,gamma,rcond=hinfsyn(p,nmeas,ncon)
315-
info = _mixsyn_info(gamma=gamma,rcond=rcond)
358+
info = gamma,rcond
316359
return k,cl,info

control/statesp.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
import math
5555
import numpy as np
5656
from numpy import all, angle, any, array, asarray, concatenate, cos, delete, \
57-
dot, empty, exp, eye, matrix, ones, pi, poly, poly1d, roots, shape, sin, \
57+
dot, empty, exp, eye, matrix, ones, poly, poly1d, roots, shape, sin, \
5858
zeros, squeeze
5959
from numpy.random import rand, randn
6060
from numpy.linalg import solve, eigvals, matrix_rank
@@ -71,9 +71,19 @@
7171

7272

7373
def _matrix(a):
74-
"""_matrix(a) -> numpy.matrix
75-
a - passed to numpy.matrix
76-
Wrapper around numpy.matrix; unlike that function, _matrix([]) will be 0x0
74+
"""Wrapper around numpy.matrix that reshapes empty matrices to be 0x0
75+
76+
Parameters
77+
----------
78+
a: sequence passed to numpy.matrix
79+
80+
Returns
81+
-------
82+
am: result of numpy.matrix(a), except if a is empty, am will be 0x0.
83+
84+
numpy.matrix([]) has size 1x0; for empty StateSpace objects, we
85+
need 0x0 matrices, so use this instead of numpy.matrix in this
86+
module.
7787
"""
7888
from numpy import matrix
7989
am = matrix(a)

control/tests/robust_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,9 +363,9 @@ def testSiso(self):
363363
np.testing.assert_allclose(cltest.C, clref.C)
364364
np.testing.assert_allclose(cltest.D, clref.D)
365365

366-
np.testing.assert_allclose(gam, info.gamma)
366+
np.testing.assert_allclose(gam, info[0])
367367

368-
np.testing.assert_allclose(rcond, info.rcond)
368+
np.testing.assert_allclose(rcond, info[1])
369369

370370

371371
if __name__ == "__main__":

0 commit comments

Comments
 (0)