Метод линеаризации нелинейных звеньев

Я должен был выложить эту статью вчера вечером, как и обещал, но этому мне помешала советская виниловая техника, которая требует полного разбора независимо от серьезности поломки.

Продолжу делаться секретами ТАУ. На этот раз вопрос коснется линеаризации. Очень часто два параметра связаны между собой нелинейной зависимостью. Гиперболической, параболической, логарифмической и т. п. Это очень неудобно при ведении расчетов. К примеру, у нас имеется энкодер на выходе которого серия импульсов. Частота вращения энкодера обратно-пропорциональна периоду следования импульсов. Общая задача — получить обратную связь по скорости. Вся шкала от 0 до 100% должна получиться относительно линейной, дабы впоследствии обеспечить стабилизацию скорости.
По катом графики из Calca, много воды и капелька теории:

В openOffice Calc построим нашу кривую по исходной зависимости:

Зависимость частоты вращения энкодера в процентах от периода следования импульсов в тиках таймера.

Как видите, для нахождения частоты вращения придется делить. Это ресурсозатратно. Более того, это у нас гипербола, а где-то может быть логарифм. Это еще хуже. Нужно упрощать. Нужно линеаризовать. В чем заключается линеаризация? Тут может быть два подхода.

Возьмем, к примеру, кривую насыщения стали:

Если работать в диапазоне 0-а, то можно считать, что данный элемент линеен. Смысл такой задачи —ограничить себя в рабочем диапазоне. Где-то это подходит. Где-то нет.

В нашем случае правильным решением будет другой способ — мы разобьем нашу кривую на интервалы. К примеру кривую насыщения можно разбить на участки 0-а, а-б, б-… Внутри этого участка зависимость между напряженностью магнитного поля и намагниченностью грубо говоря прямо пропорциональна.

Разобьем наш график на два участка. Вот так:

Грубовато выглядит, согласен. Лучшим вариантом бы было разбить кривую на три участка. Но в нашем случае и этого достаточно.
Воспользуемся формулой отрезка:

Из графика определим координаты:

И вычислим наши функции:
Для участка малых скоростей:

Для участка больших скоростей:

Посмотрим что у нас получилось:

Да, вполне сойдет. Как раз на больших скоростях малая погрешность. Теперь посмотрим как выглядит зависимость между абсолютной и относительной скоростями:

Ну, в области малых скоростей все выглядит не самым лучшим образом, но на глаз мы там толком ничего и не увидим, а вот в области больших скоростей относительно линейно. Лично меня вполне устраивает подобный результат.
Теперь все что нужно — по приходу очередного импульса от энкодера использовать следующий код:
//у меня этот код вызывается таймером, отвечающим за ШИМ привода.
tic++;
if (Encoder.Impulse){
	if (tic>130)//частота вращения больше 22%
		speed=-0,016*tic+24;
	else //частота вращения меньше 22%
		speed=-0,76*tic+121;	
tic=0;
}
else{//на нулевой скорости период следования импульсов равен бесконечности
	if (tic>2000){//поэтому если мы превысили некоторую мыслимую величину
		speed=0;//то считаем что энкодер неподвижен.
		tic-=1000;//тики приравнивать к нулю при этом нельзя —если следующим тиком придет импульс, то привод насчитает огромную скорость.
	}
}


Описанный здесь метод не претендует на звание единственного и повторимого. Основной смысл данной статьи — рекомендация моделировать и рассчитывать подобные вещи.
В следующие разы мы рассмотрим цифровые реализации типовых звеньев и постепенно создадим библиотеку компонентов.

5 комментариев

avatar
есть такой метод минимизации ошибки — наименьших квадратов. Он бы совсем не так прямые провел…
avatar
Да, кстати. Точки разделения прямых нужно не ручками от балды выбирать, а юзать соответствующий мат.аппарат.
avatar
Согласен, но в данном вараинте меня устроило именно такое решение.
avatar
Спасибо за статью.
Есще такой вопрос: Есть шаговый двигатель, он управляется сигналами step(шаг) и dir(направление вращения) через хардварный драйвер. Каким образом реализовать функцию которая бы предовала параметры (в функцию обработки срабатывания таймера) или вызывалась по срабатыванию таймера и выдавала соответсвующие сигналы step и dir, при этом параметры следующие: начальная скорость вращения; конечная скорость вращеня; значение ускорения.
avatar
Я писал нечто такое. Забрать можно вот тут. Писал я это очень быстро, но оно работает в реальном проекте и работает хорошо. Обратной связи, как у автора там нет, ускорение просто по шажкам шагового двигателя.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.