Beispiel #1
0
    def test_repr_str(self):
        # repr printing
        array = np.array
        sys0 = FrequencyResponseData([1.0, 0.9 + 0.1j, 0.1 + 2j, 0.05 + 3j],
                                     [0.1, 1.0, 10.0, 100.0])
        sys1 = FrequencyResponseData(sys0.fresp, sys0.omega, smooth=True)
        ref0 = "FrequencyResponseData(" \
            "array([[[1.  +0.j , 0.9 +0.1j, 0.1 +2.j , 0.05+3.j ]]])," \
            " array([  0.1,   1. ,  10. , 100. ]))"
        ref1 = ref0[:-1] + ", smooth=True)"
        sysm = FrequencyResponseData(np.matmul(array([[1], [2]]), sys0.fresp),
                                     sys0.omega)

        assert repr(sys0) == ref0
        assert repr(sys1) == ref1
        sys0r = eval(repr(sys0))
        np.testing.assert_array_almost_equal(sys0r.fresp, sys0.fresp)
        np.testing.assert_array_almost_equal(sys0r.omega, sys0.omega)
        sys1r = eval(repr(sys1))
        np.testing.assert_array_almost_equal(sys1r.fresp, sys1.fresp)
        np.testing.assert_array_almost_equal(sys1r.omega, sys1.omega)
        assert (sys1.ifunc is not None)

        refs = """Frequency response data
Freq [rad/s]  Response
------------  ---------------------
       0.100           1        +0j
       1.000         0.9      +0.1j
      10.000         0.1        +2j
     100.000        0.05        +3j"""
        assert str(sys0) == refs
        assert str(sys1) == refs

        # print multi-input system
        refm = """Frequency response data
Input 1 to output 1:
Freq [rad/s]  Response
------------  ---------------------
       0.100           1        +0j
       1.000         0.9      +0.1j
      10.000         0.1        +2j
     100.000        0.05        +3j
Input 2 to output 1:
Freq [rad/s]  Response
------------  ---------------------
       0.100           2        +0j
       1.000         1.8      +0.2j
      10.000         0.2        +4j
     100.000         0.1        +6j"""
        assert str(sysm) == refm
Beispiel #2
0
def test_frd():
    """Test FrequencyResonseData margins"""
    f = np.array([
        0.005, 0.010, 0.020, 0.030, 0.040, 0.050, 0.060, 0.070, 0.080, 0.090,
        0.100, 0.200, 0.300, 0.400, 0.500, 0.750, 1.000, 1.250, 1.500, 1.750,
        2.000, 2.250, 2.500, 2.750, 3.000, 3.250, 3.500, 3.750, 4.000, 4.250,
        4.500, 4.750, 5.000, 6.000, 7.000, 8.000, 9.000, 10.000
    ])
    gain = np.array([
        0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.2, 0.3,
        0.5, 0.5, -0.4, -2.3, -4.8, -7.3, -9.6, -11.7, -13.6, -15.3, -16.9,
        -18.3, -19.6, -20.8, -22.0, -23.1, -24.1, -25.0, -25.9, -29.1, -31.9,
        -34.2, -36.2, -38.1
    ])
    phase = np.array([
        0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -19, -29, -40, -51, -81,
        -114, -144, -168, -187, -202, -214, -224, -233, -240, -247, -253, -259,
        -264, -269, -273, -277, -280, -292, -301, -307, -313, -317
    ])
    # calculate response as complex number
    resp = 10**(gain / 20) * np.exp(1j * phase / (180. / np.pi))
    # frequency response data
    fresp = FrequencyResponseData(resp, f * 2 * np.pi, smooth=True)
    s = TransferFunction([1, 0], [1])
    G = 1. / (s**2)
    K = 1.
    C = K * (1 + 1.9 * s)
    TFopen = fresp * C * G
    gm, pm, sm, wg, wp, ws = stability_margins(TFopen)
    assert_allclose([pm], [44.55], atol=.01)
Beispiel #3
0
def test_frd_indexing():
    """Test FRD edge cases

    Make sure frd objects with non benign data do not raise exceptions when
    the stability criteria evaluate at the first or last frequency point
    bug reported in gh-407
    """
    # frequency points just a little under 1. and over 2.
    w = np.linspace(.99, 2.01, 11)

    # Note: stability_margins will convert the frd with smooth=True

    # gain margins
    # p crosses -180 at w[0]=1. and w[-1]=2.
    m = 0.6
    p = -180 * (2 * w - 1)
    d = m * np.exp(1J * np.pi / 180 * p)
    frd_gm = FrequencyResponseData(d, w)
    gm, _, _, wg, _, _ = stability_margins(frd_gm, returnall=True)
    assert_allclose(gm, [1 / m, 1 / m], atol=0.01)
    assert_allclose(wg, [1., 2.], atol=0.01)

    # phase margins
    # m crosses 1 at w[0]=1. and w[-1]=2.
    m = -(2 * w - 3)**4 + 2
    p = -90.
    d = m * np.exp(1J * np.pi / 180 * p)
    frd_pm = FrequencyResponseData(d, w)
    _, pm, _, _, wp, _ = stability_margins(frd_pm, returnall=True)
    assert_allclose(pm, [90., 90.], atol=0.01)
    assert_allclose(wp, [1., 2.], atol=0.01)

    # stability margins
    # minimum abs(d+1)=1-m at w[1]=1. and w[-2]=2., in nyquist plot
    w = np.arange(.9, 2.1, 0.1)
    m = 0.6
    p = -180 * (2 * w - 1)
    d = m * np.exp(1J * np.pi / 180 * p)
    frd_sm = FrequencyResponseData(d, w)
    _, _, sm, _, _, ws = stability_margins(frd_sm, returnall=True)
    assert_allclose(sm, [1 - m, 1 - m], atol=0.01)
    assert_allclose(ws, [1., 2.], atol=0.01)
Beispiel #4
0
def test_stability_margins_omega(tsys):
    sys, refout, refoutall = tsys
    """Test stability_margins() with interpolated frequencies"""
    omega = np.logspace(-2, 2, 2000)
    out = stability_margins(FrequencyResponseData(sys, omega))
    assert_allclose(out, refout, atol=1.5e-3)