Цель работы
В моей статье [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 else A*sin(w*t)*B/abs(A*sin(w*t)) for t in range(N)])
plt.plot(arange(N)/float(FD), sinp_sig, 'r')#график сигнала
plt.xlabel('Время, сек.')
plt.ylabel('Амплитуда сигнала')
plt.title('Форма сигнала c насыщением')
plt.grid(True)
plt.show()
spectr_sinp = rfft(sinp_sig )
plt.plot(rfftfreq(N, 1./FD), np_abs(spectr_sinp)/N)#график спектра
plt.xlabel('Частота, Гц')
plt.ylabel('Амплитуда сигнала')
plt.title('Спектр сигнала с насыщением')
plt.grid(True)
plt.show()
Для учёта знака ограничения 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))<B else 0 for t in range(N)])
plt.plot(arange(N)/float(FD), sinn_sig, 'r')
plt.xlabel('Время, сек.')
plt.ylabel('Амплитуда сигнала')
plt.title('Форма сигнала cо спадом')
plt.grid(True)
plt.show()
spectr_sinn = rfft(sinn_sig )
plt.plot(rfftfreq(N, 1./FD), np_abs(spectr_sinn)/N)#график спектра
plt.xlabel('Частота, Гц')
plt.ylabel('Амплитуда сигнала со спадом ')
plt.title('Спектр сигнала со спадом')
plt.grid(True)
plt.show()
Результаты
Сигнала на входе и на выходе нелинейных элементов.
![](https://habrastorage.org/files/97a/402/4e7/97a4024e78a34f4096d324affd0ee049.png)
![](https://habrastorage.org/files/2ae/4c3/203/2ae4c32037fb4797a9881471b4e18c0e.png)
![](https://habrastorage.org/files/107/c54/1bb/107c541bb6fe4c2aadb2fd5e0ea9b36e.png)
Спектры сигналов на выходе нелинейных элементов.
![](https://habrastorage.org/files/fdd/5dc/dcd/fdd5dcdcd0a644f4a4a5d8d7e142aa0f.png)
![](https://habrastorage.org/files/ee1/5bb/e66/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))<B else 0 for i in test_t ])
#test_signal=array([A*sin(2*pi*test_f* i) if abs(A*sin(2*pi*test_f* i))<B else A*sin(2*pi*test_f* i)*B/abs(A*sin(2*pi*test_f* i)) for i in test_t ])
![](https://habrastorage.org/files/178/f38/a4a/178f38a4ac144616b00d799daf7bdfd3.png)
![](https://habrastorage.org/files/952/a03/18d/952a0318d0fe43ce88533b4f7b127b5f.png)
Спектр сигнала на выходе фильтра.
![](https://habrastorage.org/files/e6b/2be/d70/e6b2bed70ad94ffca959fe8b508f67a2.png)
Вывод
Решить задачу использования нелинейных элементов можно аппаратно используя микропроцессор, но при этом необходимо согласование уровней сигналов, а так же ЦАП и АЦП.
Ссылки
1. Метод гармонической линеаризации средствами Python
2. Метод гармонической линеаризации
3. Цифровой фильтр
Поделиться с друзьями
basilbasilbasil
если есть потребность в аппаратном воплощении — может имеет смысл взять сигмоиду попроще?
например, y(x)=x/(abs(x)+a)