Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions control/dtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ def sample_system(sysc, Ts, method='zoh', alpha=None, prewarp_frequency=None):
if not isctime(sysc):
raise ValueError("First argument must be continuous time system")

return sysc.sample(Ts, method, alpha, prewarp_frequency)
return sysc.sample(Ts,
method=method, alpha=alpha, prewarp_frequency=prewarp_frequency)
Comment thread
sawyerbfuller marked this conversation as resolved.
Resolved


def c2d(sysc, Ts, method='zoh', prewarp_frequency=None):
Expand Down Expand Up @@ -126,6 +127,7 @@ def c2d(sysc, Ts, method='zoh', prewarp_frequency=None):
"""

# Call the sample_system() function to do the work
sysd = sample_system(sysc, Ts, method, prewarp_frequency)
sysd = sample_system(sysc, Ts,
method=method, prewarp_frequency=prewarp_frequency)
Comment thread
sawyerbfuller marked this conversation as resolved.
Resolved

return sysd
20 changes: 12 additions & 8 deletions control/margins.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,14 +283,16 @@ def stability_margins(sysdata, returnall=False, epsw=0.0, method='best'):
-------
gm : float or array_like
Gain margin
pm : float or array_loke
pm : float or array_like
Phase margin
sm : float or array_like
Stability margin, the minimum distance from the Nyquist plot to -1
wpc : float or array_like
Phase crossover frequency (where phase crosses -180 degrees)
Phase crossover frequency (where phase crosses -180 degrees), which is
associated with the gain margin.
wgc : float or array_like
Gain crossover frequency (where gain crosses 1)
Gain crossover frequency (where gain crosses 1), which is associated
with the phase margin.
wms : float or array_like
Stability margin frequency (where Nyquist plot is closest to -1)

Expand Down Expand Up @@ -522,10 +524,12 @@ def margin(*args):
Gain margin
pm : float
Phase margin (in degrees)
wpc : float or array_like
Phase crossover frequency (where phase crosses -180 degrees)
wgc : float or array_like
Gain crossover frequency (where gain crosses 1)
wcg : float or array_like
Crossover frequency associated with gain margin (phase crossover
frequency), where phase crosses below -180 degrees.
wcp : float or array_like
Crossover frequency associated with phase margin (gain crossover
frequency), where gain crosses below 1.

Margins are calculated for a SISO open-loop system.

Expand All @@ -536,7 +540,7 @@ def margin(*args):
Examples
--------
>>> sys = tf(1, [1, 2, 1, 0])
>>> gm, pm, wg, wp = margin(sys)
>>> gm, pm, wcg, wcp = margin(sys)

"""
if len(args) == 1:
Expand Down
20 changes: 10 additions & 10 deletions control/tests/matlab_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,13 +355,13 @@ def testLsim_mimo(self, mimo):
def testMargin(self, siso):
"""Test margin()"""
#! TODO: check results to make sure they are OK
gm, pm, wg, wp = margin(siso.tf1)
gm, pm, wg, wp = margin(siso.tf2)
gm, pm, wg, wp = margin(siso.ss1)
gm, pm, wg, wp = margin(siso.ss2)
gm, pm, wg, wp = margin(siso.ss2 * siso.ss2 * 2)
gm, pm, wcg, wcp = margin(siso.tf1)
gm, pm, wcg, wcp = margin(siso.tf2)
gm, pm, wcg, wcp = margin(siso.ss1)
gm, pm, wcg, wcp = margin(siso.ss2)
gm, pm, wcg, wcp = margin(siso.ss2 * siso.ss2 * 2)
np.testing.assert_array_almost_equal(
[gm, pm, wg, wp], [1.5451, 75.9933, 1.2720, 0.6559], decimal=3)
[gm, pm, wcg, wcp], [1.5451, 75.9933, 1.2720, 0.6559], decimal=3)

def testDcgain(self, siso):
"""Test dcgain() for SISO system"""
Expand Down Expand Up @@ -781,12 +781,12 @@ def testCombi01(self):
# total open loop
Hol = Hc*Hno*Hp

gm, pm, wg, wp = margin(Hol)
# print("%f %f %f %f" % (gm, pm, wg, wp))
gm, pm, wcg, wcp = margin(Hol)
# print("%f %f %f %f" % (gm, pm, wcg, wcp))
np.testing.assert_allclose(gm, 3.32065569155)
np.testing.assert_allclose(pm, 46.9740430224)
np.testing.assert_allclose(wg, 0.176469728448)
np.testing.assert_allclose(wp, 0.0616288455466)
np.testing.assert_allclose(wcg, 0.176469728448)
np.testing.assert_allclose(wcp, 0.0616288455466)

def test_tf_string_args(self):
"""Make sure s and z are defined properly"""
Expand Down
12 changes: 7 additions & 5 deletions control/xferfcn.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
from itertools import chain
from re import sub
from .lti import LTI, common_timebase, isdtime, _process_frequency_response
from .exception import ControlMIMONotImplemented
from . import config

__all__ = ['TransferFunction', 'tf', 'ss2tf', 'tfdata']
Expand Down Expand Up @@ -793,9 +794,9 @@ def feedback(self, other=1, sign=-1):
if (self.ninputs > 1 or self.noutputs > 1 or
other.ninputs > 1 or other.noutputs > 1):
# TODO: MIMO feedback
raise NotImplementedError(
"TransferFunction.feedback is currently only implemented "
"for SISO functions.")
raise ControlMIMONotImplemented(
"TransferFunction.feedback is currently not implemented for "
"MIMO systems.")
dt = common_timebase(self.dt, other.dt)

num1 = self.num[0][0]
Expand Down Expand Up @@ -1117,7 +1118,7 @@ def sample(self, Ts, method='zoh', alpha=None, prewarp_frequency=None):
if not self.isctime():
raise ValueError("System must be continuous time system")
if not self.issiso():
raise NotImplementedError("MIMO implementation not available")
raise ControlMIMONotImplemented("Not implemented for MIMO systems")
if method == "matched":
return _c2d_matched(self, Ts)
sys = (self.num[0][0], self.den[0][0])
Expand Down Expand Up @@ -1373,7 +1374,8 @@ def _convert_to_transfer_function(sys, **kw):
except ImportError:
# If slycot is not available, use signal.lti (SISO only)
if sys.ninputs != 1 or sys.noutputs != 1:
raise TypeError("No support for MIMO without slycot.")
raise ControlMIMONotImplemented("Not implemented for " +
"MIMO systems without slycot.")

# Do the conversion using sp.signal.ss2tf
# Note that this returns a 2D array for the numerator
Expand Down