Министерство образования Российской Федерации
Московский государственный технический университет имени Н.Э. Баумана

Петухов В.Н.

ДИСЦИПЛИНА: УПРАВЛЕНИЕ В ТЕХНИЧЕСКИХ СИСТЕМАХ

ЛАБОРАТОРНАЯ РАБОТА № X3 
СОЗДАНИЕ В СРЕДЕ ПК "МВТУ" БЛОКА УПРАВЛЕНИЯ НА БАЗЕ НЕЧЕТКОЙ ЛОГИКИ


Москва, 2004 г.

Цель работы:

ВВЕДЕНИЕ

   Программный комплекс "МВТУ"  является динамично развивающимся проектом. Фактически каждую неделю компилируется новый вариант с дополнениями исправлениями и улучшениями. Одним из значительных дополнения является появившиеся летом 2004 года был встроенный язык программирования, существенно расширяющий возможности пакета.
   В пакетах структурного моделирования пользователь, как правило, ограничен набором блоков включенным в поставку.  Создание нового блока связано с необходимостью написания кода для динамической библиотеки dll. Подобная работа требует использования отдельного компилятора для dll, при этом процесс отладки значительно усложняется. Использование встроенного языка программирования позволяет создавать новые блоки непосредственно в процессе разработки структурной модели в среде "МВТУ". Это, в свою очередь, позволяет неограниченно расширять возможности пакета применительно к любой конкретной предметной области моделирования.  
   Зачастую неопытные пользователи при выборе пакета для моделирования ориентируются на западные пакеты типа Vissim и  Simulink, руководствуясь при этом следующими рассуждениями: "Допустим, пользователю нужно моделировать регулятор нечеткой логики. Пакет XXX имеет средства для работы с нечеткой логикой а пакет ЙЙЙ не имеет. Какой пакет выбрать?"  Подразумевая очевидный ответ, что выбирать нужно Simulink. На самом деле делая такой выбор сильно ограничивает возможности, вынуждая решать задачу так, как ее решают разработчики западного пакета создающие соответствующие блоки. К тому же Simulink по скорости счета отстает от пакета МВТУ как минимум на порядок, даже при решении простых задач, а в случае серьезных моделей отставание нарастает пропорционально сложности.
   В процессе этой работы мы расширим возможности МВТУ, в той области для которой пакет еще не применялся - создадим новые блоки для моделирования регуляторов на основе нечеткой логики с помощью встроенного языка программирования.


(к содержанию)

1. ОСНОВЫ ТЕОРИИ НЕЧЕТКОЙ ЛОГИКИ.

1.1. Что такое нечеткая логика и за чем она нужна?

   В учебниках по теории нечеткой логики часто изложение построено таким образом, что читатель даже с высшим образованием, вынужден продираться через абсолютно ненужное теоретизирование и вспоминать основы логики, теории множеств. Хотя на самом деле для объяснения основных принципов работы регуляторов на основе нечеткой логике можно обойтись без таких терминов как предикаты, коньюкция, дезьюкция, импликация и прочей высокой науки. Инженеру решающими конкретные прикладные задачи зачастую необходимо быстро получить работающее решение. В данной лабораторной работе мы  расскажем  и на конкретном примере покажем, как на самом деле просто, работает нечеткая логика.
   Что бы понять чем отличается нечеткая логика от обычной рассмотрим простой пример с краном. Обычная логика:
   Если в кране нет воды,
               значит выпили жиды.
  Если в кране есть вода,
            то еврей .... туда.

   Другими словами вода либо есть либо нет, а третьего не дано, а главное кто виноват ясно. Усложним задачу  у Вас всегда в кране есть и горячая и холодная вода. Залезаете Вы под душ и начинает крутить краны. Сначала откручиваете кран с холодной водой, затем постепенно откручивая кран доводите температуру до приемлемой. В чем разница? Теперь у Вас не только есть вода (или ее нет), как в случае обычной логики, но она еще может быть,  холодной, очень холодно, нормальной, горячей или совсем кипяток.  А задача управления, в данном случае привести температуру к нормальной.
   На этом месте можно задать такой вопрос. Если известна температура воды, то можно построить алгоритм управления открывающий нужный кран в зависимости от текущей температуры и поддерживающий заданную температуру, в МВТУ подобные алгоритмы делаются без всякой нечеткой логики, где здесь особенность?
   Отличие нечеткой логики при решении  задач управления состоит в том, что  как человек в данном примере тактильно не может определить температуру воды в градусах Кельвина, Цельсия или Фаренгейта, так и алгоритм управления не связан с точной температурой воды. Человек может почувствовать горячая вода, холодная или нормальная но при этом крутить краны в нужную сторону.
   Основная идея состоит в том чтобы отказаться от составления сложных законов управления. Если с помощью только тактильных ощущений  можно с успехом регулировать температуру воды, почему бы не попробовать такой же метод и для других задачах управления. 
   Вместо того чтобы подбирать коэффициентов для всяких ПИД регуляторов, управление осуществляется с помощь набора правил например:
1. если вода горячая то открываем кран холодной воды;
2. если вода холодная то открываем кран горячей воды
;
3. если вода холодная и кран горячей открыт полностью, то закрываем кран холодной;
4. если вода горячая и кран холодной воды открыт полностью, то закрываем кран горячей воды.
  
Как видим алгоритм управления становится простым и понятным даже первокласснику второгоднику. Если все так просто, то почему бы не строить любое управление по такому принципу?. Ответ  прост, в науке и технике, при моделировании различных процессов, как правило не используется такой чуткий и измерительный инструмент как органы человеческих чувств. Вместо интуитивно понятного сигнала "горячо" с датчиков, как правило, приходит конкретная температура в градусах Кельвина, Цельсия или Фаренгейта. Да и кран нужно не просто "закрывать" а указывать на какой угол поворачивать или с какой скоростью крутить иначе любой исполнительный механизм не работает. В следующем параграфе мы и рассмотрим как эти фундаментальные отличия железа от человека обойти.


(к содержанию)

1.2. Принцип построения алгоритма нечеткого вывода.

   Для того, чтобы можно было применять простые правила, данные, передаваемые в блок регулирования на основе нечеткой логики, должны быть преобразованы. Для этого предлагается следующие:
   Входные и выходные преобразовываются в лингвистические переменные. Каждая лингвистическая переменная характеризуется набором термов. Например лингвистическая переменная температура может иметь следующие термы  "холодно", "нормально", "горячо". Лингвистическая переменная уровень может иметь следующие термы: "низкий", "нормальный", "высокий". Лингвистическая переменная задвижка может иметь следующие термы "открывать быстро", "открывать медленно", "не трогать", "закрывать медленно", "закрывать быстро". Каждый терм описывается своей функции принадлежности µi(x), которая может принимать значения от 0 до 1.  Получив численное значение входной переменной x в блоки нечетко логики вычисляется значения µi(x) каждого терма. Это процедура называется  термином Фазификация.
 Результатом применения правила являются величина, называемая степенью истинности, а попросту число от 0 до 1.  Что бы было понятно рассмотрим пример: Есть задвижка которая открывается по сигналу уровня и простое правило:
   Если уровень низкий то задвижку открывать быстро.
У нас есть входная величина уровень h в метрах. Если величина уровня очевидно низкая (µlow(h) = 1, где µlow(h) - функция принадлежности для трема низкий), или уровень очевидно низкий ((µlow(h) = 0),  то все происходит как и в обычной логике, степень истинности правила принимает значение 1 или 0.  Нечеткость начинается если 0 < µlow(h) < 1, например = 0.5. Уровень низкий, но не очень. Соответственно и открывать задвижку нужно быстро, но не очень. В данном правиле степень истинности равна 0.5. Подобным образом происходит ее вычисления для каждого правила.
   По научному, этот процесс называется Активизация.
   Заключения из каждого правила собираются вместе для каждой лингвистической переменной, этот процесс называется Аккумуляця. Например после расчета набора правил, мы получаем результаты для лингвистической переменной задвижка:  "открывать быстро" - 0.5, "открывать медленно" - 0.3, "не трогать" - 0, "закрывать медленно"-0, "закрывать быстро"-0. Понятно, что скорость задвижки лежит где то между медленной и быстро. 
   Зная степень истинности для каждого терма выходной переменной можно рассчитать ее числовое значение. Эта процедура называется Дефазификацией.
Таким образом работа блока управления на базе нечеткой логики может быть разбита на следующие этапы:

  1. Фазификация входных переменных.
  2. Активизация заключений правил нечеткой логики.
  3. Аккумуляция заключений для каждой лингвистической переменной.
  4. Дефазификация выходных переменных.
Все эти этапы мы и сделаем в ПК МВТУ с помощью новейшего средства разработки -  встроенного языка программирования.    


(к содержанию)

2. ИСПОЛЬЗОВАНИЕ ЯЗЫКА ПРОГРАММИРОВАНИЯ В МВТУ ДЛЯ СОЗДАНИЯ РЕГУЛЯТОРА НА БАЗЕ НЕЧЕТКОЙ ЛОГИКИ.

2.1. Встроенный язык программирования.

   Этой весной разработчики ПК МВТУ сделали новый блок - язык программирования. Теперь пользователю ПК МВТУ полностью развязали руки. Любая свежая идея, случайно пришедшая в голову в процессе создания модели, может быть легко и непринужденно реализована, как говорится не отходя от кассы.  Встроенный язык программирования является настоящим языком программирования высокого уровня, и при этом обладает всеми возможностями "Нового" блока для задания дифференциальных уравнений в форме Коши. Кто-то может сказать, что настоящие языки программирования это С++, Pascal, Java. Это правда, но мы не собираемся программировать Windows GDI или SQL. Наша задача реализовать математические алгоритмы с максимальным удобством, предоставляемым возможностями классических языков программирования, не покидая среду моделирования где создается основная модель. 
   Внешний вид ПК МВТУ с открытым окном редактора языка программирования представлен  на рис. 2.1. Новый блок по умолчанию находится в закладке Динамические. Редактор языка программирования открывается по двойному клику на блоке в схемном окне.


Рис. 2.1 

   Назначение основных кнопок на панели редактора языка программирования:

   Есть два способа изучать программу читать инструкцию и работать с программой. Второй метод получил название метод научного тыка. Чтобы оценить как работает новый блок, давайте приступим к его использованию, в полном соответствии с научной методой.


(к содержанию)

2.2.  Фазификация, как это работает.

   Пора на конкретном примере посмотреть, что можно сделать, имея встроенный язык программирования в ПК МВТУ.
   Для начала займемся расчлененкой, будем расчленять исходную величину на несколько термов, рассчитывая для каждого трема функцию принадлежности. При этом мы убедимся, что это совсем просто.
   Поместите на схему три блока: Из закладки Источники возьмите блок Линейный, из закладки Данные возьмем блок Временной график, ну и наконец, самый интересный для нас блок из линейки Динамические – блок Язык программирования.
   Наша задача выполнить фазификацию переменной. Роль входной переменной будет играть линейный источник. Установите время моделирования 20 сек.Для тех кто забыл напоминаю, что для этого нужно войти в меню Моделирование/Параметры расчета и найти окошко подписанное как время интегрирования. Переменная у нас будет меняться от -1 до 1. Для этого установите параметры блока линейный как -1, 0.1 Соедините блок линейный с блоком график.
   Нажмите кнопку с убегающим человечком , и смотрите на график. Если все прошло правильно должна быть прямая линия. Ну вот прелюдия завершена и мы можно непосредственно переходить к  кодированию.
Откройте редактор блока языка программирования двойным кликом на блоке в схеме.
И забейте туда текст как на рисунке 2.2 следующий текст:


рис. 2.2

   Закройте окно, нажав красную галку . После закрытия видим, что у блока появились входной и выходной порты. На вход подайте сигнал из блока линейный ( напоминаю, что узел вставляется в линию кликом мышки с нажатой клавишей Ctrl). Ну а для того, чтобы было с чем соединить выход языка програмирования, в свойствах графика увеличьте количество входных портов до 2 и соедините выход блока программирования с графиком. На рис 2.3 приведена схема которая должна получится после всех этих манипуляций Запустите расчет и на графике должен быть косой крест как на рисунке 2.3 Входная переменная возрастает выходная переменная убывает.  


рис. 2.3

   Ну вот в принципе вы и сделали свой первый блок-программу. Правда, пользы от этой программы как от козла молока, поэтому сделаем полезную вещь, которую можно использовать, а именно, расчет функции принадлежности µ(x) типа кривой Гаусса. Формула для расчета известна:
      
Чтобы запрограмировать эту формулу, необходимо ввести в программу две переменные с и sigma, и записать код для расчета кривой.
Измените текст в блоке язык программирования на следующий:


   Очевидно, что текст помещенный в кавычки {...} является комментарием и не влияет на выполнение расчета.
   Для увеличения наглядности используйте блок фазовый портрет из закладки Данные. К верхнему входу фазового портрета подключите выход линейного блока, а к нижнему выходу языка программирования. Смотри рисунок:


рис. 2.4

Запустите расчет, на графиках появилась шишка смотри рис. 2.5.


рис. 2.5

   Две переменный с и sigma определяют вид кривой: с - это значение, при котором функция принадлежности равна единице - верхушка шишки. Sigma – параметр ширины шишки.
   Таким образом мы получили блок, который позволяет рассчитывает функцию принадлежности для входной величины. Из графиков видно, что в момент времени, когда входная переменная х = 0.5 (наклонная кривая) функция принадлежности равна единице, и чем больше х отличается от 0.5 тем меньше функция принадлежности. Имея такой блок уже сейчас можно скопировать его на схеме получать разные функции принадлежности для разных термов забивая разные значения с и sigma.
   Но мы, как говорил ныне позабытый классик, пойдем другим путем. Мы не будем засорять рабочие поле схемы большим количеством блоков, как это делается в Simulinke. Мы сделаем из одного сигнала три терма с тремя функциями принадлежности в одном блоке.
Для этого запишем функцию принадлежности как функцию. Как я уже подчеркивал это позволяет делать язык программирования МВТУ. Измените текст на следующий:

   Запустите на счет и убедитесь что ничего не изменилось. А теперь воспользуемся тем счастливым обстоятельством что, в МВТУ почти все, что может быть векторезировано, является вектором. Следовательно, и переменные могут быть векторами. Пусть, в базе правил нечеткой логике используем три терма низкий (-1) нормальный (0) и высокий (1). Соответственно вместо одного значения на выходе нужно три, каждый из которых показывает насколько величина является, низкой нормальной или высокой. Делается это легко и не принужденно.
   Переделаем переменные с, sigma и выход у в массивы из трех элементов соответственно c[3], sigma[3], у[3]. Запишем для каждого трема свои параметры функции принадлежности. И чтобы уже совсем все было правильно, сделаем присвоение значений переменным в блоке инициализации (между слов initialization и end). Это блок выполняется только одни раз при запуске расчета, незачем повторять присвоение на каждом шаге моделирования. А теперь в цикле ровно три раза, вызовем функцию принадлежности. Текст всего этого приведен ниже:

  Если сейчас нажать на кнопку то ПК МВТУ покажет вам дулю и сообщит что не может привести в соответствие какие-то размерности. Не пугайтесь с вами добрый доктор, дело в том, что фазовый портрет должен иметь на обоих портах одинаковую размерность, а у нас переменная, попавшая в язык программирования расплодилась. Необходимо, размножить переменную подаваемую на верхний вход фазового портрета. Возьмите в закладке Векторные блок размножитель, и вставьте его на схему, как показано на рисунке, а в качестве параметров размножения блока запишите 3#1. Теперь переменная преобразуется в вектор из трех одинаковых значений и фазовый портрет престанет глючить:

   Вот и все с помощью каких то 15 строчек кода мы выполнили фазификацию переменной на три трема. Сохраните эту модель на диске компьютера. В дальнейшем мы будем использовать другой метод для проверки работы кода.
Результаты моделирования представлены на рис. 2.6.


   Рассмотрим что делает этот блок. На вход подается некая переменная, на выходе получаются три функции принадлежности для трех термов низкий, нормальный и высокий. Если входная величина равна -1, то функция принадлежности к терму низкий равна 1, функции принадлежности термов нормальный соответственно - 0  и высокий - 0. При увеличении входной величины значения для терма низкий уменьшается а значение для терма нормальный увеличивается. Например когда входная величина равна -0.5 значения функции принадлежности термов низкий ~ 0.25 нормальный ~ 0.25 высокий - 0. Таким образом вместо обезличенного входного численного значения на выходе получаются три величины характеризующие уровень в термах низкий, нормальный, высокий, которые в дальнейшем используются в правилах управления.  

(к содержанию)

2.3.  Архив схем - средство для многократного использования наработок.

   Сделав такой чудесный блок не мешало бы его и сохранить для дальнейшего использования. Конечно ничего не стоит написать эти пятнадцать строк кода еще раз, но зачем нам лишняя работа, когда разработчики ПК МВТУ заботятся о вас и вашем здоровье, и сделали архив схем куда можно положить любую блок написанный пользователем.
   Подпишете, блок дав ему название Фазификация MF типа кривой Гаусса. MF это сокращение от Membership Function, что в переводе с языка пиндосов, означает функция принадлежности. После этого ткните мышкой в кнопку (Сохранить в архив схем). В появившимся окне запишите категорию Fuzzy Logic записи MF Gaussian:

  А теперь обещанный ништяк, Зайдите в меню Главное меню Опции и выберете пункт Архив схем. Появится окошко с деревом, где есть категория Fuzzy Logic с элементом MF Gaussian. Теперь созданный блок можно использовать неограниченное число раз.
   Блок вышел конечно ладным, но как всегда хочется большего, например, мне лично лень набивать каждый раз значения параметров для функции Гаусса. Довольно часто шишки термов распределены равномерно между Мах и Min  а ширина шишек Гаусса одинакова, зачем же как дятлу каждый раз забивать параметры для каждого терма, пускай компьютер это сделает сам, он же железный. Мы сообщим минимальное значение, максимальное, ширину шишки и количество термов, а ПК МВТУ пусть все раскидает по термам. Надо только его научить.
  Для этого киньте на схему блок Макроблок из закладки Субструктуры. Скопируйте наш  блок фазификации и зайдите в макроблок кликнув на нем два раза. На этом девственно чистом поле мы и сделаем суб-структуру. Рецепт прост как три копейки: бросаем порт входа, порт выхода, вставляем скопированный блок фазификации и соединяем все последовательно порт входа – фазификация – порт выхода:

На панели окна схемы есть кнопка (параметры макро блока) давите на нее и в окне параметров забейте следующий текст:

   Это те параметры, по которым входное значение будет разбито на термы. Закрываем окно, нажав на красную галку .
Заходим в редактор языка программирования и слегка меняем текст:
     
   Думаю что все понятно. Единственное можно сделать пояснения к последним строчкам. Если входная величина равна границе диапазона, то согласно алгоритму значения функции принадлежности для крайних термов равно единице. Однако, при выходе за границу диапазона значение функции принадлежности начнет уменьшатся, шишка Гаусса идет на убыль. Очень часто, это является ошибкой. Например, входная температура разбита на три терма: холодно +10 C, нормально +30 C, и горячо +55 C. Если температура 55 С это на 100% горячо (функция принадлежности = 1), и по правилам логики нужно максимально быстро крутить кран холодной воды, то при температуре 100 C, явно нужно делать тоже самое, хотя функция гаусса в этой точке может превратится в ноль. Чтобы этого не случилось введена проверка выхода значения входной величины за границу диапазона.
   Поднимитесь в главное окно и соедините блок линейный с новой субмоделью, добавьте в свойствах графика еще один порт и подключите к нему выход из суб_модели. Нажимаем на бегущего человечка. Полученные результаты показывают, что при заданных параметрах графики сливаются. Теперь меня параметры субмодели TermCount, Minimum, Maximum, Sig можно получать разные результаты фазификации.
   Подписываем полученный блок как Автоматическая фазификация FM типа кривой Гаусса и заботливо помещаем в архив схем под именем Auto MF Gaussian.


(к содержанию)

2.4. Дырявый бак управляемый нечеткой логикой.

   Прежде, чем перейти к следующим этапам работы алгоритма нечеткой логики, сделаем объект управления. Управлять будем дырявым баком.
   Управлять будем уровнем в дырявом баке. Задача проста как в школе про бассейн, в одну трубу вливается в другую выливается. Мы будем рулить расходом входа, а утечка будет происходить самотеком
   Параметры бака: высота - 2 м; Площадь сечения - 1 м; Диаметр выходного отверстия 0.05 м2.
Создайте новый проект, бросьте на схему Макроблок из закладки Субструктуры.  Войдите в блок и занесите в свойствах блока данные по баку:
  
   Динамику бака можно описать следующими уравнениями:
  
  где:    V - объем бака м3;
         rate - расход поступающий в бак м3/с;
    outrate - расход утечки м3/с;
             h - уровень в баке м;
        area - площадь сечения бака;
    outarea - площадь выходного отверстия;
    g = 9.8 - ускорение свободного падения.
Бросьте на на схему наш любимы блок Язык программирования и запишите уравнения динамики:

   Вот, чем особенно хорош Блок язык программирования ПК МВТУ, теперь пользователь что видит то и моделирует, используя язык программирования с возможностью записи дифференциальных уравнений. Если уравнения динамики известны, их нужно просто записать, не забывая указывать начальные условия для динамических ременных (здесь init V=0)и опля! - новый блок готов к работе.
 Соберите схему как показано на следующем рисунке и модель бака дырявого бак готова.

    Разберемся теперь клапаном управляющим расходом. Основная идея такова. Задается номинальный расход 0.5 м3/с. Управляющие воздействие это скорость закрытия-открытия задвижки, интегрируя данную скорость по времени мы получаем положение задвижки - число от 0 (задвижка закрыта - расход равен 0) до 1 расход равен номинальному. Зависимость расхода от положение задвижки линейная. Бросьте на основную схему новый Макроблок из закладки Субструктуры войдите в него и соберите схему как на рис. 2.8:


Рис.2.8.

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


Рис.2.9.

   Работа системы проста и незатейлива. Блок Меандр из закладки Источники задает изменение уровня с частотой 20 сек с 1.5 до 0.5, заданное значение сравнивается с реальным и разница подается на первый вход блока управления. На второй вход подается скорость изменения уровня в баке. На выходе мы получаем команду клапана который и управляет расходом в бак.


(к содержанию)

2.5. Рулез рулят или ORDNUNG, ORDNUNG UBER ALLES!

   Получив модель дырявого бака, самое время перейти к рассмотрению базы правил нечеткой логики. Для нашего бака правила блок управления на базе нечеткой логики имеет входные переменные уровень, и изменение уровня. Переменная уровень будет иметь следующие термы: 1 -высокий, 2 -нормальный, 3 -низкий. Переменная изменение уровня будет иметь такие термы: 1 - уменьшается,  2 -не изменяется, 3 -увеличивается. Блок управления клапаном  будет выдавать переменную команда клапана, которая в свою очередь, будет иметь следующие термы: 1 -закрывать быстро, 2 -закрывать медленно, 3 -не менять, 4 -открывать медленно,  5 - открывать быстро. База правил для управления будет иметь следующий вид:

  1. ЕСЛИ уровень = высокий TO команда клапана = закрывать быстро;

  2. ЕСЛИ уровень = нормальный TO команда клапана = не  изменять

  3. ЕСЛИ уровень = низкий ТО команда клапана = открывать быстро;

  4. ЕСЛИ уровень = нормальный И изменение уровня = уменьшается ТО команда клапана = открывать медленно;

  5. ЕСЛИ уровень = нормальный И изменение уровня = увеличивается ТО команда клапана = закрывать медленно;   

   Как видим на словах все абсолютно ясно и просто. Поскольку логика у нас нечеткая, для каждого правила нужно, не просто получить ответ да или нет, а рассчитать степь истинности. Для правил 1-3 степень истинности равна величание функции принадлежности для соответствующего терма. Попросту, если уровень h высокий на 0.5 (µhigh(h) = 0.5) то и степень истинности равна 0.5. Функциональная схема макроблока реализующего данное правило:
     
   Константа вес позволяет задать весовой коэффициент для правила в базе данных. Создайте новый макроблок, свяжите эту схему и пометите его в архив схем с многозначительным именем =>.
   Степень истинности правил 4 и 5 зависит от двух входных переменных, соединенных логическим И, если хотите выражаться научно, можете называть это логической конъюнкцией. Для вычисления степени истинности существует несколько вариантов, мы используем метод алгебраического произведения, (заключение правила является произведением истинности входных переменных) смотри схему макроблока:
     
  Этот макроблок тоже отправляем в архив схем под именем AND (prod). Сохранив в архиве два простых макроблока мы можем приступить к созданию нашего блока управления на базе нечеткой логики. Внутренняя структура показана на рисунке 2.10. 


Рис.2.10.

   На рисунке 2.10 картинки блоков для наглядности изменена, что совсем не влияет на функциональное наполнении блока.  Возьмите блоки, созданные на первом этапе из архива схем и поместите их на схему.  Задайте параметры автоматической фазификации в редакторе переменных соответствующего блока:
Для переменной уровень:
TermCount= 3, Minimum = -1, Maximum = 1, Sig = 0.3;
для переменной скорость изменения:
TermCount = 3, Minimum = -0.1, Maximum = 0.1, Sig = 0.03
   Самая большая сложность на этом этапе, это соединение блоков фазификации и блоков правил в нужном порядке. Вот здесь и пригодится возможность подписывать блоки. Выход из блока фазификации для каждой переменной соедините с блоком Демультиплексор, для удобства дальнейшей работы с базой правил, подпишите под блоком соответствующие название термов в том порядке в котором они расположены в векторе. Ибо ORDNUNG, ORDNUNG UBER ALLES, как говорят немцы. 
   Поместите на схему необходимое количество блоков правил.
   Выходная переменная имеет пять термов их мы будем предавать в виде вектора. Поместите на схему блок Мультиплексор и задайте 5 входных параметров. Степень истинности для каждого правила подаются на соответствующий порт Мультиплексора.  Подписи под блоком помогут правильно подключить результаты расчета степени истинности блоков правил. Помните  ORDNUNG, ORDNUNG UBER ALLES!
   Соедините схему согласно записанных правил. И сохраните заготовку.


(к содержанию)

2.6. Фазификации, активизация, аккумуляция и дефазификация в одном флаконе.

2.6.1 Фазификация входной переменной.  

   Получив вектор состоящий из пяти заключений из правил нечеткой логики, необходимо рассчитать значение выходной переменной. Для этого мы воспользуемся алгоритмом Мамдани (это не ругательство!).
    Для начала осуществим фазификацию выходной переменной на пять термов с помощью треугольных функций принадлежности. Как Вы уже догадались мы снова будем пользовать блок Язык программирования. Первая часть текста программы приведена на рисунке 2.11


Рис.2.11.

   action[5] - это массив входных значений (заключений из базы правил), который в процессе моделирования мы получим из блока Мультиплексор;
   TriangleFM - треугольная функция принадлежности.
   Записав данный кусок кода не плохо бы проверить, что мы нагородили, и тут нам на помощь приходит очередной грандиозный прорыв МВТУ. 
  За что инженеры физики уважают MachCad? Не в последнюю очередь за то, он позволяет проверить ту галиматью, которую записывают в расчетах непосредственно в процессе записи. В любой момент можно построить графическую зависимость и посмотреть не припущено-ли где возведение в степень, не стоил ли знак плюс вместо минуса или умножение вместо деления. А вот при программировании постоянно приходится вооружившись дебаггером шерстить код на предмет ошибок. Явно смущаясь программисты пользуются языком пиндосов называя это процесс поиском багов. Впрочем оставим поиск насекомых обезьянам и вернемся к ПК МВТУ.
   Чтобы убедится в отсутствии блох в написанном куске кода, построим график функции. Для этого нажмите кнопку построения графических зависимостей . При этом появится диалоговое окно Построение зависимости построения как на рис. 2.12:

 
Рис.2.12.

   Вообще-то эта возможность предназначена для построения векторных зависимостей, однако при установке галочки Скалярная зависимость "легким движением руки шорты превращаются в..." графопостроитель. В верхней строчке вводим минимальное максимальное значение х и количество точек для отображения (смотри рис 2.12). В нижнюю строку копируем функцию TriangleFM из окна "Языка программирования", задаем значения для a, b и с (смотри рис 2.12). Нажимаем на кнопку ОК и Опля! получаем график как на рисунке 2.13


Рис.2.13.

   Теперь меняя значении параметров функции TriangleFM в диалоговом окне и нажимая кнопку "ОК", можно получить графики функции при различных параметрах.
  Следующая часть листинга приведена на рисунке 2.14. Здесь описываются массивы переменных для треугольных функции фазификации выходной переменной. В секции initialization присваиваются значения переменным для каждого терма. Для проверки написанного кода, без запуска моделирования, присваиваем значения входному вектору action. Дело в том, что до начала расчета значения входных переменных в векторе action[5] равны нулю. В процессе расчета эти значения передаются по линиям связи из блока Мультиплексор (см рис. 2.10). Для проверки  можно присвоить им проверочные значения, если это сделать в секции initialization, то в последствии это присвоение можно не удалять, так как на расчет они не повлияют. В этом же разделе кода задаем количество точек для численного интегрирования IntCount и вычисляем шаг численного интегрирования dX (пригодится)


Рис.2.14.

   Заполнив значения массивов можно проверить, с помощью графика, правильность заполнения. Построить зависимости для каждого терма, используя вместо численных значений, имена переменных. Например последовательно меняя в нижнем поле диалогового окна "Построение зависимостей" текст:
TriangleFM(x,a[2],b[2],c[2]),
TriangleFM(x,a[3],b[3],c[3]),
TriangleFM(x,a[4],b[4],c[4]) и
TriangleFM(x,a[5],b[5],c[5]) каждый раз не забывая нажимать ОК можно получить зубы как на рис. 2.15


Рис.2.15.

    Параметры a[i], b[i], c[i], задаются с учетом расположения заключений правил в входном векторе смотри рис 2.10. В примере принято расположение термов по возрастанию. В принципе, расположение может быть любое. Главное соблюдать соответствие между индексом терма в векторе входа, и индексом параметров функции принадлежности терма. Соответствие термов и параметров их функций принадлежности приведены в таблице:

Index Терм Параметры функции принадлежности μi(х)
1 закрывать быстро  (-1, -0.9, -0.8)
2 закрывать медленно (-0.6, -0.5, -0.4)
3 не изменять (-0.1, 0, 0.1)
4 открывать медленно (0.3, 0.4, 0.5)
5 открывать быстро (0.8, 0.9, 1)
   На рис 2.15 изображена фазификация выходной переменной по термам, согласно таблице.
   Как видим код фазификации выходной переменной, очень похож на процесс фазификации входных переменных, такое же разбиение на термы и задание функции принадлежности для каждого терма. Отличие состоит в том, что численные значения входных переменных известны и  вычисления функции принадлежности для каждого терма выполняется в одно действие. Выходную переменную нам еще предстоит вычислить. 

2.6.2 Активизация и аккумуляция

   Следующая процедура заключается в применении заключений из правил нечеткой логики. Мы должны изменить функции принадлежности μi(х) для каждого терма выходной переменной, с учетом заключений (степени истинности actioni) из базы правил нечеткой логики. Данная процедура называется активизация.
   Есть несколько методов активизации мы рассмотрим два метода:

  1.  prod- активизации, при этом результирующая функция получается умножением степени истинности заключения из правила на соответствующую функцию принадлежности. Например если степень истинности для заключения закрывать быстро равна 0 (первое значение в массиве action ) то после умножения функция принадлежности превратится в ноль, ну а если степень истинности равна 1 то функция не изменится:
     μ'i(х) = actioni · μi(х);
  2. min - активизация, при этом результирующая функции принимает минимальное значение из степени истинности и исходной функции принадлежности μ'i(х) = MIN (actioni , μi(х));
   Одновременно с активизацией мы проведем аккумуляцию - найдем общую функцию принадлежности для выходной переменной по всем термам. Мы строим общую функцию для  заданного диапазона значений. Для этого в первом случае, функцию принадлежности каждого терма µi(x) нужно умножить на значение степени истинности соответствующего заключения (активизация), и найти максимальное значение из всех таких произведений для каждого трема в т. x (аккумуляция). В результате мы получаем огибающую функцию. Вся это заумное описание укладывается в пяток строчек кода. Алгоритм вычисления провиден на рис. 2.16.


Рис.2.16.

   Если построит функцию AccProb(x) для значения входного вектора action[5] по умолчанию (все элементы равны единицы см. рис. 2.14 ) то получится график, объединяющий  функции принадлежности для всех термов выходной переменной, как на рисунке 2.17:


Рис.2.17.

   Не зря мы присвоили в секции initialization значения вектору action. теперь просто меняя значения в тексте можно посмотреть результирующую функцию. Например, если задать входной вектор значений action = [0.2, 0.5, 0.6, 0.8, 1], (секция initialization см. рис. 2.14 ), результат расчета по приведенному коду принимает вид представленный на рисунке 2.18:


Рис.2.18.

   Код для расчета методом min - активизации и результат расчета для вектора входных значений
action = [0.2, 0.5, 0.6, 0.8, 1] приведены на рисунках 2.18 (a) и 2.18 (б):


Рис.2.18 (а).

Рис.2.18 (б).

   Таким образом работа алгоритма становится абсолютно понятной. Подаваемы на вход вектор action[5] из пяти значений, содержит степени истинности для всех правил, определяющих, то что нужно делать: закрывать быстро, закрывать медленно, не изменять, открывать медленно, открывать быстро. По полученным данным строится общая функция (см. рис 2.18) которая содержит результат правил для каждого терма (высота зуба) и параметры фазификации (расположение и форма зуба). Остается сущий пустяк произвести дефазификацию, получить из этой фигуры, где размазаны результаты правил точную цифру - скорость клапана.

2.6.3 Дефазификация.

   Нам нужно из обобщенной функции получить конкретное числовое значение. Для этого, имея результирующую функцию мы находим координату х центра масс полученной фигуры, которая и даст нам значение скорости открытия клапана. Здесь нам и пригодится значение dX, рассчитанное в секции initialization блока см.рис. 2.12. Формулу расчета центра масс знает каждый октябренок:
     
   Ну, а численный алгоритм реализующий эту формулу методом треугольников представлен на рисунке 2.19. Результат расчета предается в выходную переменную у.


Рис.2.19.

   Для проверки работоспособности кода воспользуемся встроенным калькулятором, который выполняет расчет кода без запуска процесса моделирования. Нажмите соответствующую кнопку появится список в котором перечислены имена переменных и рассчитанные значения. Например для вектора входных значений
action = [0.2, 0.5, 0.6, 0.8, 1] результат расчета центра дает значение у = 0.258,  для скорости открытия клапана.
   Если вы правильно переписали листинги кода с рисунков 2.11, 2.14, 2.16, 2.19, то при запуске расчета,  на графике, подписанном нами как уровень, из основной схемы, (смотри рис. 2.9.) отразится изменения заданного уровня (черный график) и уровня обеспечиваемого регулятором нечеткой логики:


Рис.2.20.

  Поздравляю! Вы только что своими руками создали регулятор на базе нечеткой логики. Для этого Вам пришлось написать около 70 строчек кода. При этом Вы мимоходом без напряга, получили три блока которые могут пригодится при решении подобных задач в будущем.  В отличие о пользователей MatLab, тупо заполняющих диалоговые окна, Вы теперь знаете как работает нечетка логика изнутри и может выдумывать, а главное программировать свои собственные алгоритмы. После выполнения это лабораторной работы, Вы можете спокойно начинать изучение нечеткой логики, пользуясь любым учебником. И как бы не грузили авторы Вы теперь знает, что нечеткая логика это не просто, а очень просто особенно с ПК "МВТУ". Удачи!

 
(к содержанию)

Литература:

1. Тимофеев К.А. "Описание языка программирования ПК МВТУ"
2. Козлов О.С. "Теория автоматического управления. в примерах и среда моделирования ПК МВТУ".
3. Леоненков А.В. "Нечеткое моделирование в среде MATLAB и fuzzyTECH"
 

Ссылки:

1.Сайт ПК МВТУ.
2. Последние версии ПК МВТУ.
3. Архив с проектами на тему лабораторной работы.
4. Форум где можно обсудить или осудит эту лабораторную работу.
5. Дискуссионная группа по моделированию систем.