Skip to content

Commit 7e47d80

Browse files
committed
Add wrapper like functionality for ispassive(), so that it can be called in an object oriented style as a LTI class member. Added unit tests for transfer function and oo style calls. Ran autopep8 on lti.py.
1 parent cf0eac3 commit 7e47d80

3 files changed

Lines changed: 37 additions & 6 deletions

File tree

control/lti.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"""
1414

1515
import numpy as np
16+
1617
from numpy import absolute, real, angle, abs
1718
from warnings import warn
1819
from . import config
@@ -21,6 +22,7 @@
2122
__all__ = ['poles', 'zeros', 'damp', 'evalfr', 'frequency_response',
2223
'freqresp', 'dcgain', 'pole', 'zero']
2324

25+
2426
class LTI(NamedIOSystem):
2527
"""LTI is a parent class to linear time-invariant (LTI) system objects.
2628
@@ -44,6 +46,7 @@ class LTI(NamedIOSystem):
4446
Note: dt processing has been moved to the NamedIOSystem class.
4547
4648
"""
49+
4750
def __init__(self, inputs=1, outputs=1, states=None, name=None, **kwargs):
4851
"""Assign the LTI object's numbers of inputs and ouputs."""
4952
super().__init__(
@@ -71,8 +74,7 @@ def _set_inputs(self, value):
7174

7275
#: Deprecated
7376
inputs = property(
74-
_get_inputs, _set_inputs, doc=
75-
"""
77+
_get_inputs, _set_inputs, doc="""
7678
Deprecated attribute; use :attr:`ninputs` instead.
7779
7880
The ``inputs`` attribute was used to store the number of system
@@ -94,8 +96,7 @@ def _set_outputs(self, value):
9496

9597
#: Deprecated
9698
outputs = property(
97-
_get_outputs, _set_outputs, doc=
98-
"""
99+
_get_outputs, _set_outputs, doc="""
99100
Deprecated attribute; use :attr:`noutputs` instead.
100101
101102
The ``outputs`` attribute was used to store the number of system
@@ -201,6 +202,11 @@ def _dcgain(self, warn_infinite):
201202
else:
202203
return zeroresp
203204

205+
def ispassive(self):
206+
# importing here prevents circular dependancy
207+
from control.passivity import ispassive
208+
ispassive(self)
209+
204210
#
205211
# Deprecated functions
206212
#
@@ -321,7 +327,7 @@ def damp(sys, doprint=True):
321327
wn, damping, poles = sys.damp()
322328
if doprint:
323329
print('_____Eigenvalue______ Damping___ Frequency_')
324-
for p, d, w in zip(poles, damping, wn) :
330+
for p, d, w in zip(poles, damping, wn):
325331
if abs(p.imag) < 1e-12:
326332
print("%10.4g %10.4g %10.4g" %
327333
(p.real, 1.0, -p.real))
@@ -330,6 +336,7 @@ def damp(sys, doprint=True):
330336
(p.real, p.imag, d, w))
331337
return wn, damping, poles
332338

339+
333340
def evalfr(sys, x, squeeze=None):
334341
"""Evaluate the transfer function of an LTI system for complex frequency x.
335342
@@ -388,6 +395,7 @@ def evalfr(sys, x, squeeze=None):
388395
"""
389396
return sys.__call__(x, squeeze=squeeze)
390397

398+
391399
def frequency_response(sys, omega, squeeze=None):
392400
"""Frequency response of an LTI system at multiple angular frequencies.
393401

control/passivity.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
'''
55

66
import numpy as np
7+
from control import statesp as ss
78

89
try:
910
import cvxopt as cvx
@@ -35,6 +36,8 @@ def ispassive(sys):
3536
if cvx is None:
3637
raise ModuleNotFoundError("cvxopt required for passivity module")
3738

39+
sys = ss._convert_to_statespace(sys)
40+
3841
A = sys.A
3942
B = sys.B
4043
C = sys.C

control/tests/passivity_test.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
'''
55
import pytest
66
import numpy
7-
from control import ss, passivity
7+
from control import ss, passivity, tf
88
from control.tests.conftest import cvxoptonly
99

1010

@@ -51,3 +51,23 @@ def test_ispassive_edge_cases(test_input, expected):
5151
D = test_input[3]
5252
sys = ss(A, B, C, D)
5353
assert(passivity.ispassive(sys) == expected)
54+
55+
56+
def test_transfer_function():
57+
sys = tf([1], [1, -2])
58+
assert(passivity.ispassive(sys))
59+
60+
sys = tf([1], [1, 2])
61+
assert(not passivity.ispassive(sys))
62+
63+
64+
def test_oo_style():
65+
A = numpy.array([[0, 1], [-2, -2]])
66+
B = numpy.array([[0], [1]])
67+
C = numpy.array([[-1, 2]])
68+
D = numpy.array([[1.5]])
69+
sys = ss(A, B, C, D)
70+
assert(sys.ispassive())
71+
72+
sys = tf([1], [1, -2])
73+
assert(sys.ispassive())

0 commit comments

Comments
 (0)