8000 docstring improvements, pep8 cleanup, more descriptive names for inte… · python-control/python-control@e808adb · GitHub
[go: up one dir, main page]

Skip to content

Commit e808adb

Browse files
committed
docstring improvements, pep8 cleanup, more descriptive names for internal variables
1 parent feb9010 commit e808adb

File tree

2 files changed

+48
-44
lines changed

2 files changed

+48
-44
lines changed

control/rlocus.py

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def root_locus(sys, kvect=None, xlim=None, ylim=None,
8888
----------
8989
sys : LTI object
9090
Linear input/output systems (SISO only, for now).
91-
kvect : list or ndarray, optional
91+
kvect : float or array_like, optional
9292
List of gains to use in computing diagram.
9393
xlim : tuple or list, optional
9494
Set limits of x axis, normally with tuple
@@ -110,10 +110,11 @@ def root_locus(sys, kvect=None, xlim=None, ylim=None,
110110
111111
Returns
112112
-------
113-
rlist : ndarray
114-
Computed root locations, given as a 2D array
115-
klist : ndarray or list
116-
Gains used. Same as klist keyword argument if provided.
113+
roots : ndarray
114+
Closed-loop root locations, arranged in which each row corresponds
115+
to a gain in gains
116+
gains : ndarray
117+
Gains used. Same as kvect keyword argument if provided.
117118
118119
Notes
119120
-----
@@ -145,10 +146,12 @@ def root_locus(sys, kvect=None, xlim=None, ylim=None,
145146
print_gain = config._get_param(
146147
'rlocus', 'print_gain', print_gain, _rlocus_defaults)
147148

148-
sys_loop = sys if sys.issiso() else sys[0, 0]
149+
if not sys.issiso():
150+
raise ControlMIMONotImplemented(
151+
'sys must be single-input single-output (SISO)')
149152

150153
# Convert numerator and denominator to polynomials if they aren't
151-
(nump, denp) = _systopoly1d(sys_loop)
154+
(nump, denp) = _systopoly1d(sys)
152155

153156
# if discrete-time system and if xlim and ylim are not given,
154157
# that we a view of the unit circle
@@ -158,12 +161,13 @@ def root_locus(sys, kvect=None, xlim=None, ylim=None,
158161
xlim = (-1.3, 1.3)
159162

160163
if kvect is None:
161-
start_mat = _RLFindRoots(nump, denp, [1])
162-
kvect, mymat, xlim, ylim = _default_gains(nump, denp, xlim, ylim)
164+
start_roots = _RLFindRoots(nump, denp, 1)
165+
kvect, root_array, xlim, ylim = _default_gains(nump, denp, xlim, ylim)
163166
else:
164-
start_mat = _RLFindRoots(nump, denp, [kvect[0]])
165-
mymat = _RLFindRoots(nump, denp, kvect)
166-
mymat = _RLSortRoots(mymat)
167+
kvect = np.atleast_1d(kvect)
168+
start_roots = _RLFindRoots(nump, denp, kvect[0])
169+
root_array = _RLFindRoots(nump, denp, kvect)
170+
root_array = _RLSortRoots(root_array)
167171

168172
# Check for sisotool mode
169173
sisotool = False if 'sisotool' not in kwargs else True
@@ -190,10 +194,10 @@ def root_locus(sys, kvect=None, xlim=None, ylim=None,
190194
ax_rlocus=fig.axes[0], plotstr=plotstr))
191195
elif sisotool:
192196
fig.axes[1].plot(
193-
[root.real for root in start_mat],
194-
[root.imag for root in start_mat],
197+
[root.real for root in start_roots],
198+
[root.imag for root in start_roots],
195199
marker='s', markersize=6, zorder=20, color='k', label='gain_point')
196-
s = start_mat[0][0]
200+
s = start_roots[0][0]
197201
if isdtime(sys, strict=True):
198202
zeta = -np.cos(np.angle(np.log(s)))
199203
else:
@@ -229,7 +233,7 @@ def root_locus(sys, kvect=None, xlim=None, ylim=None,
229233
ax.plot(real(zeros), imag(zeros), 'o')
230234

231235
# Now plot the loci
232-
for index, col in enumerate(mymat.T):
236+
for index, col in enumerate(root_array.T):
233237
ax.plot(real(col), imag(col), plotstr, label='rootlocus')
234238

235239
# Set up plot axes and labels
@@ -257,7 +261,7 @@ def root_locus(sys, kvect=None, xlim=None, ylim=None,
257261
(0, 0), radius=1.0, linestyle=':', edgecolor='k',
258262
linewidth=0.75, fill=False, zorder=-20))
259263

260-
return mymat, kvect
264+
return root_array, kvect
261265

262266

263267
def _default_gains(num, den, xlim, ylim, zoom_xlim=None, zoom_ylim=None):
@@ -509,28 +513,27 @@ def _RLFindRoots(nump, denp, kvect):
509513
"""Find the roots for the root locus."""
510514
# Convert numerator and denominator to polynomials if they aren't
511515
roots = []
512-
for k in np.array(kvect, ndmin=1):
516+
for k in 23D3 np.atleast_1d(kvect):
513517
curpoly = denp + k * nump
514518
curroots = curpoly.r
515519
if len(curroots) < denp.order:
516520
# if I have fewer poles than open loop, it is because i have
517521
# one at infinity
518-
curroots = np.insert(curroots, len(curroots), np.inf)
522+
curroots = np.append(curroots, np.inf)
519523

520524
curroots.sort()
521525
roots.append(curroots)
522526

523-
mymat = row_stack(roots)
524-
return mymat
527+
return row_stack(roots)
525528

526529

527-
def _RLSortRoots(mymat):
528-
"""Sort the roots from sys._RLFindRoots, so that the root
530+
def _RLSortRoots(roots):
531+
"""Sort the roots from _RLFindRoots, so that the root
529532
locus doesn't show weird pseudo-branches as roots jump from
530533
one branch to another."""
531534

532-
sorted = zeros_like(mymat)
533-
for n, row in enumerate(mymat):
535+
sorted = zeros_like(roots)
536+
for n, row in enumerate(roots):
534537
if n == 0:
535538
sorted[n, :] = row
536539
else:
@@ -539,7 +542,7 @@ def _RLSortRoots(mymat):
539542
# previous row
540543
available = list(range(len(prevrow)))
541544
for elem in row:
542-
evect = elem-prevrow[available]
545+
evect = elem - prevrow[available]
543546
ind1 = abs(evect).argmin()
544547
ind = available.pop(ind1)
545548
sorted[n, ind] = elem
@@ -549,9 +552,7 @@ def _RLSortRoots(mymat):
549552

550553
def _RLZoomDispatcher(event, sys, ax_rlocus, plotstr):
551554
"""Rootlocus plot zoom dispatcher"""
552-
sys_loop = sys if sys.issiso() else sys[0,0]
553-
554-
nump, denp = _systopoly1d(sys_loop)
555+
nump, denp = _systopoly1d(sys)
555556
xlim, ylim = ax_rlocus.get_xlim(), ax_rlocus.get_ylim()
556557

557558
kvect, mymat, xlim, ylim = _default_gains(
@@ -583,9 +584,7 @@ def _RLClickDispatcher(event, sys, fig, ax_rlocus, plotstr, sisotool=False,
583584

584585
def _RLFeedbackClicksPoint(event, sys, fig, ax_rlocus, sisotool=False):
585586
"""Display root-locus gain feedback point for clicks on root-locus plot"""
586-
sys_loop = sys if sys.issiso() else sys[0,0]
587-
588-
(nump, denp) = _systopoly1d(sys_loop)
587+
(nump, denp) = _systopoly1d(sys)
589588

590589
xlim = ax_rlocus.get_xlim()
591590
ylim = ax_rlocus.get_ylim()
@@ -596,10 +595,10 @@ def _RLFeedbackClicksPoint(event, sys, fig, ax_rlocus, sisotool=False):
596595
# Catch type error when event click is in the figure but not in an axis
597596
try:
598597
s = complex(event.xdata, event.ydata)
599-
K = -1. / sys_loop(s)
600-
K_xlim = -1. / sys_loop(
598+
K = -1. / sys(s)
599+
K_xlim = -1. / sys(
601600
complex(event.xdata + 0.05 * abs(xlim[1] - xlim[0]), event.ydata))
602-
K_ylim = -1. / sys_loop(
601+
K_ylim = -1. / sys(
603602
complex(event.xdata, event.ydata + 0.05 * abs(ylim[1] - ylim[0])))
604603

605604
except TypeError:

control/sisotool.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,19 @@ def sisotool(sys, kvect=None, xlim_rlocus=None, ylim_rlocus=None,
2929
sys : LTI object
3030
Linear input/output systems. If sys is SISO, use the same
3131
system for the root locus and step response. If it is desired to
32-
see a different step response than feedback(K*loop,1), sys can be
33-
provided as a two-input, two-output system (e.g. by using
34-
:func:`bdgalg.connect' or :func:`iosys.interconnect`). Sisotool
35-
inserts the negative of the selected gain K between the first output
36-
and first input and uses the second input and output for computing
37-
the step response. This allows you to see the step responses of more
38-
complex systems, for example, systems with a feedforward path into the
39-
plant or in which the gain appears in the feedback path.
32+
see a different step response than feedback(K*sys,1), such as a
33+
disturbance response, sys can be provided as a two-input, two-output
34+
system (e.g. by using :func:`bdgalg.connect' or
35+
:func:`iosys.interconnect`). For two-input, two-output
36+
system, sisotool inserts the negative of the selected gain K between
37+
the first output and first input and uses the second input and output
38+
for computing the step response. To see the disturbance response,
39+
configure your plant to have as its second input the disturbance input.
40+
To view the step response with a feedforward controller, give your
41+
plant two identical inputs, and sum your feedback controller and your
42+
feedforward controller and multiply them into your plant's second
43+
input. It is also possible to accomodate a system with a gain in the
44+
feedback.
4045
kvect : float or array_like, optional
4146
List of gains to use for plotting root locus. If only one value is
4247
provided, the set of gains in the root locus plot is calculated
@@ -115,7 +120,7 @@ def sisotool(sys, kvect=None, xlim_rlocus=None, ylim_rlocus=None,
115120
1 if kvect is None else kvect[0], bode_plot_params)
116121

117122
# Setup the root-locus plot window
118-
root_locus(sys, kvect=kvect, xlim=xlim_rlocus,
123+
root_locus(sys[0,0], kvect=kvect, xlim=xlim_rlocus,
119124
ylim=ylim_rlocus, plotstr=plotstr_rlocus, grid=rlocus_grid,
120125
fig=fig, bode_plot_params=bode_plot_params, tvect=tvect, sisotool=True)
121126

0 commit comments

Comments
 (0)
0