Skip to content

Commit 4788f6b

Browse files
authored
Merge pull request python-control#547 from murrayrm/doc_updates
Small documentation updates
2 parents bb2cdea + 0c78aff commit 4788f6b

File tree

3 files changed

+45
-34
lines changed

3 files changed

+45
-34
lines changed

control/freqplot.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,7 @@ def nyquist_plot(syslist, omega=None, plot=True, omega_limits=None,
608608
be 'right' (default), 'left', or 'none'.
609609
610610
warn_nyquist : bool, optional
611-
If set to `False', turn off warnings about frequencies above Nyquist.
611+
If set to 'False', turn off warnings about frequencies above Nyquist.
612612
613613
*args : :func:`matplotlib.pyplot.plot` positional properties, optional
614614
Additional arguments for `matplotlib` plots (color, linestyle, etc)

control/margins.py

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -211,36 +211,40 @@ def fun(wdt):
211211
# Sawyer B. Fuller <minster@uw.edu>, removed a lot of the innards
212212
# and replaced with analytical polynomial functions for LTI systems.
213213
#
214-
# idea for the frequency data solution copied/adapted from
214+
# The idea for the frequency data solution copied/adapted from
215215
# https://github.com/alchemyst/Skogestad-Python/blob/master/BODE.py
216216
# Rene van Paassen <rene.vanpaassen@gmail.com>
217217
#
218218
# RvP, July 8, 2014, corrected to exclude phase=0 crossing for the gain
219219
# margin polynomial
220+
#
220221
# RvP, July 8, 2015, augmented to calculate all phase/gain crossings with
221222
# frd data. Correct to return smallest phase
222223
# margin, smallest gain margin and their frequencies
223-
# RvP, Jun 10, 2017, modified the inclusion of roots found for phase
224-
# crossing to include all >= 0, made subsequent calc
225-
# insensitive to div by 0
226-
# also changed the selection of which crossings to
227-
# return on basis of "A note on the Gain and Phase
224+
#
225+
# RvP, Jun 10, 2017, modified the inclusion of roots found for phase crossing
226+
# to include all >= 0, made subsequent calc insensitive to
227+
# div by 0. Also changed the selection of which crossings
228+
# to return on basis of "A note on the Gain and Phase
228229
# Margin Concepts" Journal of Control and Systems
229-
# Engineering, Yazdan Bavafi-Toosi, Dec 2015, vol 3
230-
# issue 1, pp 51-59, closer to Matlab behavior, but
231-
# not completely identical in edge cases, which don't
232-
# cross but touch gain=1
230+
# Engineering, Yazdan Bavafi-Toosi, Dec 2015, vol 3 issue
231+
# 1, pp 51-59, closer to Matlab behavior, but not
232+
# completely identical in edge cases, which don't cross but
233+
# touch gain=1.
234+
#
233235
# BG, Nov 9, 2020, removed duplicate implementations of the same code
234236
# for crossover frequencies and enhanced to handle discrete
235237
# systems
238+
239+
236240
def stability_margins(sysdata, returnall=False, epsw=0.0):
237241
"""Calculate stability margins and associated crossover frequencies.
238242
239243
Parameters
240244
----------
241245
sysdata: LTI system or (mag, phase, omega) sequence
242246
sys : LTI system
243-
Linear SISO system
247+
Linear SISO system representing the loop transfer function
244248
mag, phase, omega : sequence of array_like
245249
Arrays of magnitudes (absolute values, not dB), phases (degrees),
246250
and corresponding frequencies. Crossover frequencies returned are
@@ -255,18 +259,25 @@ def stability_margins(sysdata, returnall=False, epsw=0.0):
255259
256260
Returns
257261
-------
258-
gm: float or array_like
262+
gm : float or array_like
259263
Gain margin
260-
pm: float or array_loke
264+
pm : float or array_loke
261265
Phase margin
262-
sm: float or array_like
266+
sm : float or array_like
263267
Stability margin, the minimum distance from the Nyquist plot to -1
264-
wg: float or array_like
265-
Frequency for gain margin (at phase crossover, phase = -180 degrees)
266-
wp: float or array_like
267-
Frequency for phase margin (at gain crossover, gain = 1)
268-
ws: float or array_like
269-
Frequency for stability margin (complex gain closest to -1)
268+
wpc : float or array_like
269+
Phase crossover frequency (where phase crosses -180 degrees)
270+
wgc : float or array_like
271+
Gain crossover frequency (where gain crosses 1)
272+
wms : float or array_like
273+
Stability margin frequency (where Nyquist plot is closest to -1)
274+
275+
Note that the gain margin is determined by the gain of the loop
276+
transfer function at the phase crossover frequency(s), the phase
277+
margin is determined by the phase of the loop transfer function at
278+
the gain crossover frequency(s), and the stability margin is
279+
determined by the frequency of maximum sensitivity (given by the
280+
magnitude of 1/(1+L)).
270281
"""
271282
try:
272283
if isinstance(sysdata, frdata.FRD):
@@ -398,7 +409,8 @@ def _dstab(w):
398409
(not SM.shape[0] and float('inf')) or np.amin(SM),
399410
(not gmidx != -1 and float('nan')) or w_180[gmidx][0],
400411
(not wc.shape[0] and float('nan')) or wc[pmidx][0],
401-
(not wstab.shape[0] and float('nan')) or wstab[SM==np.amin(SM)][0])
412+
(not wstab.shape[0] and float('nan')) or
413+
wstab[SM == np.amin(SM)][0])
402414

403415

404416
# Contributed by Steffen Waldherr <waldherr@ist.uni-stuttgart.de>
@@ -455,7 +467,7 @@ def margin(*args):
455467
----------
456468
sysdata : LTI system or (mag, phase, omega) sequence
457469
sys : StateSpace or TransferFunction
458-
Linear SISO system
470+
Linear SISO system representing the loop transfer function
459471
mag, phase, omega : sequence of array_like
460472
Input magnitude, phase (in deg.), and frequencies (rad/sec) from
461473
bode frequency response data
@@ -466,17 +478,16 @@ def margin(*args):
466478
Gain margin
467479
pm : float
468480
Phase margin (in degrees)
469-
wg: float
470-
Frequency for gain margin (at phase crossover, phase = -180 degrees)
471-
wp: float
472-
Frequency for phase margin (at gain crossover, gain = 1)
481+
wpc : float or array_like
482+
Phase crossover frequency (where phase crosses -180 degrees)
483+
wgc : float or array_like
484+
Gain crossover frequency (where gain crosses 1)
473485
474486
Margins are calculated for a SISO open-loop system.
475487
476-
If there is more than one gain crossover, the one at the smallest
477-
margin (deviation from gain = 1), in absolute sense, is
478-
returned. Likewise the smallest phase margin (in absolute sense)
479-
is returned.
488+
If there is more than one gain crossover, the one at the smallest margin
489+
(deviation from gain = 1), in absolute sense, is returned. Likewise the
490+
smallest phase margin (in absolute sense) is returned.
480491
481492
Examples
482493
--------
@@ -491,6 +502,6 @@ def margin(*args):
491502
margin = stability_margins(args)
492503
else:
493504
raise ValueError("Margin needs 1 or 3 arguments; received %i."
494-
% len(args))
505+
% len(args))
495506

496507
return margin[0], margin[1], margin[3], margin[4]

doc/descfcn.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ nonlinearity constructors are predefined:
5959

6060
.. code:: python
6161
62-
backlash_nonlinearity(b) # backlash nonlinearity with width b
62+
friction_backlash_nonlinearity(b) # backlash nonlinearity with width b
6363
relay_hysteresis_nonlinearity(b, c) # relay output of amplitude b with
6464
# hysteresis of half-width c
6565
saturation_nonlinearity(ub[, lb]) # saturation nonlinearity with upper
@@ -81,6 +81,6 @@ Module classes and functions
8181
:toctree: generated/
8282

8383
~control.DescribingFunctionNonlinearity
84-
~control.backlash_nonlinearity
84+
~control.friction_backlash_nonlinearity
8585
~control.relay_hysteresis_nonlinearity
8686
~control.saturation_nonlinearity

0 commit comments

Comments
 (0)