Как вы генерируете сигнал обратной реакции для простого синусоидального ввода с использованием python?

#python #numpy #matplotlib

#python #numpy #matplotlib

Вопрос:

Я использую приведенные ниже коды 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()
  

введите описание изображения здесь

введите описание изображения здесь

Комментарии:

1. Пожалуйста, обратитесь к прилагаемому изображению. Выходные данные должны быть аналогичны указанным на изображении.

2. Пожалуйста, предоставьте другую часть головоломки. Нам нужно видеть как то, что вы получаете, так и то, что вы ожидаете.

3. @Mark Setchell: Я получаю выходные данные, как показано на втором изображении. Это не соответствует требованию. Первое изображение [выше] является обязательным, а изображение ниже [второе] — это то, что я получаю в качестве выходных данных. Вывод должен следовать за вводом после пересечения пороговых значений, как показано на первом изображении [выше].

Ответ №1:

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

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

где h находится половина мертвой зоны.

Следующий скрипт включает backlash функцию, которая использует цикл Python for. (Функция использует 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()
  

график

Обновление: я реализовал backlash функцию как NumPy gufunc в моем репозитории ufunclab.

Комментарии:

1. Действительно инженерный ответ. Векторизация немного сложна для этого выходного сигнала, а затем следует за входным сигналом с задержкой на определенный временной шаг. 1 голос за ваш ответ.