Как вы генерируете сигнал обратной реакции для простого синусоидального ввода с использованием Python? - PullRequest
0 голосов
/ 24 марта 2019

Я использую приведенные ниже коды python для генерации сигнала обратной реакции для простого синусоидального входа. Сгенерированный выходной сигнал не соответствует требованию. Выходной сигнал должен быть аналогичен выходному сигналу блока обратной реакции, используемого в Simulink.

#Importing libraries 
import matplotlib.pyplot as plt
import numpy as np

#Setting upper limit and lower limit
LL = -0.5
UL = 0.5

#Generating the sine wave
x=np.linspace(0,10,1000)
y=(np.sin(x))

#phase shift of y1 by -pi/2
y1=(np.sin(x-1.571))

# plot original sine
plt.plot(x,y)

#setting the thresholds 
y1[(y1>UL)] = UL
y1[(y1<LL)] = LL

#Initializing at the input
y1[(y==0)]  = 0

y1[(y1>UL)] -= UL
y1[(y1<LL)] -= LL

#Plotting both the waves
plt.plot(x,y)
plt.plot(x,y1)

plt.grid()
plt.show()

enter image description here

enter image description here

1 Ответ

1 голос
/ 25 марта 2019

Я не думаю, что есть простая векторизованная реализация для процесса обратной реакции.K-й вывод зависит от предыдущих значений нетривиальным образом.Краткий способ записать процесс (при условии x - это входной массив, а y - это выходной массив):

y[k] = min(max(y[k-1], x[k] - h), x[k] + h)

, где h - половина зоны нечувствительности.

Следующий скрипт включает функцию backlash, которая использует цикл for Python.(Функция использует операторы if вместо функций min и max.) Это просто, но не очень быстро.Если важна высокая производительность, вы можете рассмотреть возможность переопределения функции в Cython или numba .

import numpy as np


def backlash(x, deadband=1.0, initial=0.0):
    """
    Backlash process.

    This function emulates the Backlash block of Simulink
    (https://www.mathworks.com/help/simulink/slref/backlash.html).

    x must be a one-dimensional numpy array (or array-like).
    deadband must be a nonnegative scalar.
    initial must be a scalar.
    """
    halfband = 0.5*deadband

    y = np.empty_like(x, dtype=np.float64)
    current_y = initial

    for k in range(len(x)):
        current_x = x[k]
        xminus = current_x - halfband
        if xminus > current_y:
            current_y = xminus
        else:
            xplus = current_x + halfband
            if xplus < current_y:
                current_y = xplus
        y[k] = current_y

    return y


if __name__ == "__main__":
    import matplotlib.pyplot as plt

    t = np.linspace(0, 10, 500)
    x = np.sin(t)
    deadband = 1
    y = backlash(x, deadband=deadband)

    plt.plot(t, x, label='x(t)')
    plt.plot(t, y, '--', label='backlash(x(t))')
    plt.xlabel('t')

    plt.legend(framealpha=1, shadow=True)
    plt.grid(alpha=0.5)
    plt.show()

plot

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...