|
11 | 11 | from warnings import warn |
12 | 12 | from . import config |
13 | 13 | from .iosys import InputOutputSystem |
| 14 | +import control |
| 15 | +from typing import Callable |
14 | 16 |
|
15 | 17 | __all__ = ['poles', 'zeros', 'damp', 'evalfr', 'frequency_response', |
16 | 18 | 'freqresp', 'dcgain', 'bandwidth', 'LTI'] |
@@ -76,9 +78,10 @@ def frequency_response(self, omega=None, squeeze=None): |
76 | 78 |
|
77 | 79 | Parameters |
78 | 80 | ---------- |
79 | | - omega : float or 1D array_like |
| 81 | + omega : float or 1D array_like, optional |
80 | 82 | A list, tuple, array, or scalar value of frequencies in |
81 | | - radians/sec at which the system will be evaluated. |
| 83 | + radians/sec at which the system will be evaluated. If None (default), |
| 84 | + a set of frequencies is computed based on the system dynamics. |
82 | 85 | squeeze : bool, optional |
83 | 86 | If squeeze=True, remove single-dimensional entries from the shape |
84 | 87 | of the output even if the system is not SISO. If squeeze=False, |
@@ -107,6 +110,11 @@ def frequency_response(self, omega=None, squeeze=None): |
107 | 110 | """ |
108 | 111 | from .frdata import FrequencyResponseData |
109 | 112 |
|
| 113 | + if omega is None: |
| 114 | + # Use default frequency range |
| 115 | + from .freqplot import _default_frequency_range |
| 116 | + omega = _default_frequency_range(self) |
| 117 | + |
110 | 118 | omega = np.sort(np.array(omega, ndmin=1)) |
111 | 119 | if self.isdtime(strict=True): |
112 | 120 | # Convert the frequency to discrete time |
@@ -202,6 +210,34 @@ def ispassive(self): |
202 | 210 | # importing here prevents circular dependancy |
203 | 211 | from control.passivity import ispassive |
204 | 212 | return ispassive(self) |
| 213 | + |
| 214 | + def feedback(self, other=1, sign=-1): |
| 215 | + raise NotImplementedError(f"feedback not implemented for base {self.__class__.__name__} objects") |
| 216 | + |
| 217 | + # convenience aliases |
| 218 | + # most function are only forward declaraed and patched in the __init__.py to avoid circular imports |
| 219 | + |
| 220 | + # conversions |
| 221 | + #: Convert to :class:`StateSpace` representation; see :func:`ss` |
| 222 | + to_ss: Callable |
| 223 | + #: Convert to :class:`TransferFunction` representation; see :func:`tf` |
| 224 | + to_tf: Callable |
| 225 | + |
| 226 | + # freq domain plotting |
| 227 | + #: Bode plot; see :func:`bode_plot` |
| 228 | + bode_plot: Callable |
| 229 | + #: Nyquist plot; see :func:`nyquist_plot` |
| 230 | + nyquist_plot: Callable |
| 231 | + #: Nichols plot; see :func:`nichols_plot` |
| 232 | + nichols_plot: Callable |
| 233 | + |
| 234 | + # time domain simulation |
| 235 | + #: Forced response; see :func:`forced_response` |
| 236 | + forced_response = control.timeresp.forced_response |
| 237 | + #: Impulse response; see :func:`impulse_response` |
| 238 | + impulse_response = control.timeresp.impulse_response |
| 239 | + #: Step response; see :func:`step_response` |
| 240 | + step_response = control.timeresp.step_response |
205 | 241 |
|
206 | 242 |
|
207 | 243 | def poles(sys): |
|
0 commit comments