Спектральный анализ сигналов нелинейных звеньев АСУ на Python

Цель работы


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

Этот метод может быть использован в том случае, когда линейная часть системы является низкочастотным фильтром, т.е. отфильтровывает все возникающие на выходе нелинейного элемента гармонические составляющие, кроме первой гармоники [2]. Поэтому логическим продолжением моей первой статьи будет гармонический анализ рассмотренных нелинейных элементов. Кроме этого нужно рассмотреть аппаратную альтернативу методу гармонической линеаризации.

Метод анализа и программный код


Пусть на нелинейные элементы поступает чистый синусоидальный сигнал. Методом разложения в дискретный ряд Фурье получим его спектр.
#!/usr/bin/env python
#coding=utf8
from numpy import array, arange, abs as np_abs
from numpy.fft import rfft, rfftfreq
from math import sin, pi
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.rcParams['font.family'] = 'fantasy'
mpl.rcParams['font.fantasy'] = 'Comic Sans MS, Arial'
FD = 250000#частота дискретизации, отсчётов в секунду
N = 2500#длина входного массива, N/FD секунд 
F=250.0#циклическая частота входного сигнала
w=(2.*pi*F/FD)#отсчёт круговой частоты 
A=3.0#амплитуда сигнала
B=0.5#порог ограничения
#сгенерируем чистый синусоидальный сигнал с частотой F длиной N
sin_sig = array([A*sin(w*t) for t in range(N)])#график сигнала
plt.plot(arange(N)/float(FD), sin_sig, 'r')
plt.xlabel('Время, сек.')
plt.ylabel('Амплитуда  сигнала')
plt.title('Входной синусоидальный сигнала')
plt.grid(True)
plt.show()
spectr_sin = rfft(sin_sig )#вычисляем дискретное действительное rfft  преобразование Фурье
plt.plot(rfftfreq(N, 1./FD), np_abs(spectr_sin)/N) #график спектра
plt.xlabel('Частота, Гц')
plt.ylabel('Амплитуда  сигнала')
plt.title('Спектр синусоидального сигнала')
plt.grid(True)
plt.show()

Получим сигнал и спектр сигнала с выхода нелинейного элемента с «насыщением».
# сгенерируем сигнал нелинейности c «насыщением» из A*sin(w*t) при abs(А)>abs(B)
sinp_sig =array([A*sin(w*t) if abs(A*sin(w*t))

Для учёта знака ограничения B использован следующий код — A*sin (w*t)*B/abs (A*sin (w*t).

Получим вид сигнала и спектр нелинейного элемента с переходом амплитуды в ноль.

# сгенерируем сигнал нелинейности «cо спадом до нуля»  из A*sin(w*t) при abs(А)=abs(B)
sinn_sig = array([A*sin(w*t) if abs(A*sin(w*t))

Результаты


Сигнала на входе и на выходе нелинейных элементов.

97a4024e78a34f4096d324affd0ee049.png

2ae4c32037fb4797a9881471b4e18c0e.png

107c541bb6fe4c2aadb2fd5e0ea9b36e.png

Спектры сигналов на выходе нелинейных элементов.

fdd5dcdcd0a644f4a4a5d8d7e142aa0f.png

ee15bbe663504833b2cd5afd4d590529.png

Нелинейный элемент со спадом сигнала генерирует большое число высокочастотных гармоник. Для фильтрации сигнала на выходе нелинейных элементов можно применить цифровой НЧ фильтр, детально описанный в работе [3]. Для исследования возможностей цифровой фильтрации сигналов нелинейных элементов в код программы [3], были внесены следующие изменения.

A=1.0
B=0.4
test_n = 2560 # Кол-во отсчётов тестового сигнала
test_f = 200 # Наименьшая отличная от нуля частота тестового сигнала
test_period_count = 10.0 # Кол-во периодов тестового сигнала
test_t = numpy.linspace(0.0, test_period_count/test_f, test_n)
# Базовый сигнал sin(wt), подлежащий восстановлению фильтром
test_base_signal = array([A*sin(2*pi*test_f* i) for i in test_t ])
test_signal =array([A*sin(2*pi*test_f* i) if abs(sin(2*pi*test_f* i))

178f38a4ac144616b00d799daf7bdfd3.png

952a0318d0fe43ce88533b4f7b127b5f.png

Спектр сигнала на выходе фильтра.

e6b2bed70ad94ffca959fe8b508f67a2.png

Вывод


Решить задачу использования нелинейных элементов можно аппаратно используя микропроцессор, но при этом необходимо согласование уровней сигналов, а так же ЦАП и АЦП.

Ссылки


1. Метод гармонической линеаризации средствами Python
2. Метод гармонической линеаризации
3. Цифровой фильтр

Комментарии (1)

  • 3 апреля 2017 в 14:39

    0

    если есть потребность в аппаратном воплощении — может имеет смысл взять сигмоиду попроще?
    например, y (x)=x/(abs (x)+a)

© Habrahabr.ru