Модельно-ориентированное проектирование на коленке, идентификация систем в MATLAB/Simulink



    Привет, Хабр!

    Сегодня я хочу показать простой пример идентификации системы, основываясь на наблюдениях и экспериментальных данных. Это первая и крайне важная ступень в разработке системы управления устройством, которое описать аналитически либо невозможно, либо слишком сложно, либо неохота. Для начала рассмотрим метод «черного ящика с котом», «серый» и «белый» методы оставим на следующий раз.
    Интересующихся прошу под кат.

    Оборудование и программное обеспечение в наличии


    • Watchdog Watchduck:

      Выполняет ту же функцию, что и Watchdog timer, но применительно к инженеру — помогает выйти из зависания.

    • Машина реального времени Speedgoat. Немного проще, нежели на заглавной иллюстрации, примерно такая:


      В данном ПК (а это по сути и есть IBM совместимый ПК) присутствуют платы ввода-вывода с аналоговыми, дискретными, и прочими входами и выходами, которые я использую как для сбора данных, так и для управления ходом эксперимента. Но самое главное — я могу одним нажатием запускать на ней модели Simulink в режиме жесткого реального времени. О таких машинках (да простят мне уменьшительно-ласкательное дальнейшее к Ней обращение:-) я много еще могу рассказать. Если интересно — можно выделить для этого отдельный топик.

    • MATLAB/Simulink

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

    • Двигатель постоянного тока с энкодером и зубчатой передачей от Pololu. Вот такой:

    • Arduino + Motor Shield от seeedstudio

      Для работы с Arduino из-под Simulink я использую библиотеку Embedded Coder Target for Arduino.
      Эта библиотека позволяет использовать модели Simulink для генерации кода полностью готового к компиляции под данную платформу. Можно использовать также встроенную поддержку Arduino в MATLAB/Simulink, но мне данный таргет более по душе.

    • Макетная плата, проводники, питание и прочая мелочевка

    На самом деле, любой из представленных компонентов может быть заменён на соответствующий функциональный аналог (кроме утки, конечно!). Но, так как делалось все «на коленке» — то и право выбора остается за владельцем этого важного сустава.

    В собранном виде, если это можно назвать собранностью, все выглядит так:


    Постановка задачи


    Есть система — необходимо получить её модель для дальнейшей работы. Проще некуда.
    Поведение системы и её модели должно максимально совпадать в пределах допустимых входных воздействий. Метод «черного ящика» подразумевает, что мы не будем, или почти не будем, принимать во внимание физику процессов внутри системы, а будем рассматривать её с общей точки зрения теории управления.

    В детали я вдаваться в этот раз не буду, поначалу все и так видно, на глаз.
    Но следует учесть, что за кулисами остаются архиважные и преинтереснейшие темы — планирование эксперимента (DOE) и дисперсионный анализ (ANOVA), которые заслуживают отдельного рассмотрения.

    Целевая система в некотором приближении и с упрощением состоит из следующего набора подсистем:
    • Дискретная подсистема — Arduino
    • Непрерывная механическая подсистема — двигатель
    • Непрерывная электрическая подсистема — Motor Shield

    Вход системы — заданное значение ШИМ 0-100%.
    Еесть возможность изменять скважность ШИМ сигнала, подавая на выход «аналогового» порта Arduino значения uint8 от 0 до 255. Необходимо узнать, как будет реагировать силовая электроника и двигатель на это воздействие.
    Тестовый вектор будет зашит в контроллер, состоит он из 501 элемента и выдается с дискретизацией 0.04с. Итого ~20 секунд тестового воздействия.
    Выглядит тестовый вектор так:


    На выходе системы я ожидаю увидеть хоть что-то подобное :-)
    Для успешной идентификации тестовый вектор должен покрывать максимальное количество режимов работы системы, в которых она будет, или может работать. Метод «черного ящика» не позволяет в полной мере исследовать аварийные режимы ввиду ограниченности количества экспериментальных образцов. Я буду исследовать систему в рабочих режимах плавного пуска и старт-стоп.

    Выход системы — скорость вращения вала, угол поворота вала. С квадратурного энкодера, при вращении вала двигателя, я получаю два меандра со смещением по фазе на pi/2. Их обрабатывает аппаратный декодер, который присутствует на одной из конфигурируемых плат ввода-вывода. При загрузке модели Simulink на машину реального времени происходит «прошивка» ПЛИС (FPGA) для обеспечения требуемых входов/выходов. Тики, с декодера умножаем на коэффициент и превращаем в угол, а скорость изменения их количества в скорость. Энкодер двигателя делает 64 триггирования за один оборот, что позволяет с хорошей точностью отслеживать описанные выше параметры. Основной алгоритм на машине реального времени установлен мною на работу с частотой 10 kHz — на выходе я получаю экспериментальные данные с периодом дискретизации 0,0001с. Аппаратная же часть ПЛИС работает на частоте 33 MHz, что позволяет, помимо основного алгоритма декодирования, успевать применить еще и антидребезговые алгоритмы без ущерба точности измерениям на довольно высоких оборотах. Простыми словами декодирование квадратурного сигнала на FPGA описано в прекрасной статье fpga4fun --> QuadratureDecoder.

    Дискретизация величин, временные задержки, моменты инерции механических деталей, трение спокойствия, трение скольжения, трение качения, механический люфт, разбалансировка, резонансные явления, коммутация индуктивных цепей, скользящий контакт, искрение — не полный перечень факторов, с которыми нам пришлось бы столкнуться при попытке описать данную систему аналитически. А ведь это — всего лишь ардуинка с моторчиком!
    Соглашусь, некоторыми нюансами вполне можно пренебречь, но на практике, решение пренебречь каким-либо фактором — не самое простое решение.

    Так выглядит ШИМ из Arduino (желтый) и напряжение на чисто резистивной нагрузке, которая подключена к шилду:



    А вот графики при подключенном двигателе в режимах, когда двигатель еще не вращается, и уже вращается:





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

    Модели Simulink


    На машине реального времени я запускаю вот такую модель:



    Структура её крайне проста. Есть блоки для входов, выходов, общие настройки плат ввода-вывода, вывод информации на дисплей машинки и простая внутренняя логика пересчета тиков от квадратурного энкодера в угол и скорость.

    Модель для получения прошивки под Arduino выглядит следующим образом:



    Таблица истинности, которая отслеживает знак сигнала и управляет входами Motor Shield



    Код алгоритма можно посмотреть под спойлером:
    C++
    //
    // File: arduinoTestVector.cpp
    //
    // Code generated for Simulink model 'arduinoTestVector'.
    //
    // Model version                  : 1.229
    // Simulink Coder version         : 8.6 (R2014a) 27-Dec-2013
    // C/C++ source code generated on : Thu May 22 14:47:55 2014
    //
    // Target selection: arduino_ec.tlc
    // Embedded hardware selection: Atmel->AVR
    // Code generation objectives:
    //    1. Execution efficiency
    //    2. ROM efficiency
    //    3. RAM efficiency
    // Validation result: Not run
    //
    #include "arduinoTestVector.h"
    
    // Constant parameters (auto storage)
    const ConstParam_arduinoTestVector arduinoTestVector_ConstP = {
      // Expression: myData
      //  Referenced by: '<S1>/Constant1'
    
      { 0, 1, 3, 4, 5, 6, 8, 9, 10, 11, 13, 14, 15, 17, 18, 19, 20, 22, 23, 24, 26,
        27, 28, 29, 31, 32, 33, 34, 36, 37, 38, 40, 41, 42, 43, 45, 46, 47, 48, 50,
        51, 52, 54, 55, 56, 57, 59, 60, 61, 62, 0, -1, -3, -4, -5, -6, -8, -9, -10,
        -11, -13, -14, -15, -17, -18, -19, -20, -22, -23, -24, -26, -27, -28, -29,
        -31, -32, -33, -34, -36, -37, -38, -40, -41, -42, -43, -45, -46, -47, -48,
        -50, -51, -52, -54, -55, -56, -57, -59, -60, -61, -62, 0, 3, 5, 8, 10, 13,
        15, 18, 20, 23, 26, 28, 31, 33, 36, 38, 41, 43, 46, 48, 51, 54, 56, 59, 61,
        64, 66, 69, 71, 74, 77, 79, 82, 84, 87, 89, 92, 94, 97, 99, 102, 105, 107,
        110, 112, 115, 117, 120, 122, 125, 0, -3, -5, -8, -10, -13, -15, -18, -20,
        -23, -26, -28, -31, -33, -36, -38, -41, -43, -46, -48, -51, -54, -56, -59,
        -61, -64, -66, -69, -71, -74, -77, -79, -82, -84, -87, -89, -92, -94, -97,
        -99, -102, -105, -107, -110, -112, -115, -117, -120, -122, -125, 170, 170,
        170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
        170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
        170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170,
        170, 170, 170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170,
        -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170,
        -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170,
        -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170, -170,
        -170, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, -255, -255, -255, -255, -255, -255, -255, -255,
        -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255,
        -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255,
        -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, -255,
        -255, -255, -255, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
        85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
        85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, -85, -85,
        -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
        -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85,
        -85, -85, -85, -85, -85, -85, -85, -85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
    };
    
    // Block signals (auto storage)
    BlockIO_arduinoTestVector arduinoTestVector_B;
    
    // Block states (auto storage)
    D_Work_arduinoTestVector arduinoTestVector_DWork;
    
    // Model step function
    void arduinoTestVector_step(void)
    {
      // local block i/o variables
      uint8_T rtb_MOTORSHIELD_IN1;
      uint8_T rtb_MOTORSHIELD_IN2;
      uint8_T rtb_Abs;
      boolean_T aVarTruthTableCondition_1;
      boolean_T aVarTruthTableCondition_2;
      boolean_T aVarTruthTableCondition_3;
      uint16_T rtb_Init;
    
      // Outputs for Enabled SubSystem: '<Root>/ENABLE_TEST' incorporates:
      //   EnablePort: '<S1>/Enable'
    
      // S-Function (sfunar_digitalInput): '<Root>/RUN_TEST'
      if (((uint8_T)digitalRead(((uint8_T)2U))) > 0) {
        if (!arduinoTestVector_DWork.ENABLE_TEST_MODE) {
          // InitializeConditions for UnitDelay: '<S1>/Unit Delay'
          arduinoTestVector_DWork.UnitDelay_DSTATE = false;
    
          // InitializeConditions for UnitDelay: '<S4>/FixPt Unit Delay2'
          arduinoTestVector_DWork.FixPtUnitDelay2_DSTATE = 1U;
    
          // InitializeConditions for UnitDelay: '<S4>/FixPt Unit Delay1'
          arduinoTestVector_DWork.FixPtUnitDelay1_DSTATE = 0U;
          arduinoTestVector_DWork.ENABLE_TEST_MODE = true;
        }
    
        // Switch: '<S4>/Init' incorporates:
        //   Constant: '<S4>/Initial Condition'
        //   Logic: '<S4>/FixPt Logical Operator'
        //   UnitDelay: '<S1>/Unit Delay'
        //   UnitDelay: '<S4>/FixPt Unit Delay1'
        //   UnitDelay: '<S4>/FixPt Unit Delay2'
    
        if (arduinoTestVector_DWork.UnitDelay_DSTATE ||
            (arduinoTestVector_DWork.FixPtUnitDelay2_DSTATE != 0)) {
          rtb_Init = 0U;
        } else {
          rtb_Init = arduinoTestVector_DWork.FixPtUnitDelay1_DSTATE;
        }
    
        // End of Switch: '<S4>/Init'
    
        // Selector: '<S1>/Selector' incorporates:
        //   Constant: '<S1>/Constant1'
    
        arduinoTestVector_B.Selector = arduinoTestVector_ConstP.Constant1_Value
          [(int16_T)rtb_Init];
    
        // Switch: '<S4>/Reset' incorporates:
        //   UnitDelay: '<S1>/Unit Delay'
    
        if (arduinoTestVector_DWork.UnitDelay_DSTATE) {
          // Update for UnitDelay: '<S4>/FixPt Unit Delay1' incorporates:
          //   Constant: '<S4>/Initial Condition'
    
          arduinoTestVector_DWork.FixPtUnitDelay1_DSTATE = 0U;
        } else {
          // Update for UnitDelay: '<S4>/FixPt Unit Delay1' incorporates:
          //   Constant: '<S1>/Constant'
          //   Sum: '<S1>/Add'
    
          arduinoTestVector_DWork.FixPtUnitDelay1_DSTATE = rtb_Init + 1U;
        }
    
        // End of Switch: '<S4>/Reset'
    
        // Update for UnitDelay: '<S1>/Unit Delay' incorporates:
        //   Constant: '<S3>/Constant'
        //   RelationalOperator: '<S3>/Compare'
    
        arduinoTestVector_DWork.UnitDelay_DSTATE = (rtb_Init == 500U);
    
        // Update for UnitDelay: '<S4>/FixPt Unit Delay2' incorporates:
        //   Constant: '<S4>/FixPt Constant'
    
        arduinoTestVector_DWork.FixPtUnitDelay2_DSTATE = 0U;
      } else {
        if (arduinoTestVector_DWork.ENABLE_TEST_MODE) {
          // Disable for Outport: '<S1>/TEST_OUT'
          arduinoTestVector_B.Selector = 0;
          arduinoTestVector_DWork.ENABLE_TEST_MODE = false;
        }
      }
    
      // End of S-Function (sfunar_digitalInput): '<Root>/RUN_TEST'
      // End of Outputs for SubSystem: '<Root>/ENABLE_TEST'
    
      // Truth Table: '<Root>/Truth Table'
      // Truth Table Function 'Truth Table': '<S2>:1'
      //  ClockWise
      // Condition '#1': '<S2>:1:10'
      aVarTruthTableCondition_1 = (arduinoTestVector_B.Selector > 0);
    
      //  CounterClockWise
      // Condition '#2': '<S2>:1:14'
      aVarTruthTableCondition_2 = (arduinoTestVector_B.Selector < 0);
    
      //  Stop
      // Condition '#3': '<S2>:1:18'
      aVarTruthTableCondition_3 = (arduinoTestVector_B.Selector == 0);
      if ((!aVarTruthTableCondition_1) && (!aVarTruthTableCondition_2) &&
          aVarTruthTableCondition_3) {
        // Decision 'D1': '<S2>:1:20'
        //  Stop
        // Action '3': '<S2>:1:48'
        rtb_MOTORSHIELD_IN1 = 0U;
    
        // Action '3': '<S2>:1:49'
        rtb_MOTORSHIELD_IN2 = 0U;
      } else {
        // Decision 'D2': '<S2>:1:20'
        if (aVarTruthTableCondition_1 && (!aVarTruthTableCondition_2) &&
            (!aVarTruthTableCondition_3)) {
          // Decision 'D2': '<S2>:1:22'
          //  ClockWise
          // Action '1': '<S2>:1:34'
          rtb_MOTORSHIELD_IN1 = 1U;
    
          // Action '1': '<S2>:1:35'
          rtb_MOTORSHIELD_IN2 = 0U;
        } else {
          // Decision 'D3': '<S2>:1:22'
          if ((!aVarTruthTableCondition_1) && aVarTruthTableCondition_2 &&
              (!aVarTruthTableCondition_3)) {
            // Decision 'D3': '<S2>:1:24'
            //  CounterClockWise
            // Action '2': '<S2>:1:41'
            rtb_MOTORSHIELD_IN1 = 0U;
    
            // Action '2': '<S2>:1:42'
            rtb_MOTORSHIELD_IN2 = 1U;
          } else {
            // Decision 'D4': '<S2>:1:24'
            // Decision 'D4': '<S2>:1:26'
            //  Default
            //  None
            // Action '4': '<S2>:1:55'
            rtb_MOTORSHIELD_IN1 = 0U;
    
            // Action '4': '<S2>:1:56'
            rtb_MOTORSHIELD_IN2 = 0U;
          }
        }
      }
    
      // End of Truth Table: '<Root>/Truth Table'
    
      // S-Function (sfunar_digitalOutput): '<Root>/MOTORSHIELD_IN1'
      digitalWrite(((uint8_T)8U), rtb_MOTORSHIELD_IN1);
    
      // S-Function (sfunar_digitalOutput): '<Root>/MOTORSHIELD_IN2'
      digitalWrite(((uint8_T)11U), rtb_MOTORSHIELD_IN2);
    
      // Abs: '<Root>/Abs'
      if (arduinoTestVector_B.Selector < 0) {
        rtb_Abs = (uint8_T)-arduinoTestVector_B.Selector;
      } else {
        rtb_Abs = (uint8_T)arduinoTestVector_B.Selector;
      }
    
      // End of Abs: '<Root>/Abs'
    
      // S-Function (sfunar_analogOutput): '<Root>/SPEEDPIN_A'
      analogWrite(((uint8_T)9U), rtb_Abs);
    }
    
    // Model initialize function
    void arduinoTestVector_initialize(void)
    {
      // Registration code
    
      // block I/O
      (void) memset(((void *) &arduinoTestVector_B), 0,
                    sizeof(BlockIO_arduinoTestVector));
    
      // states (dwork)
      (void) memset((void *)&arduinoTestVector_DWork, 0,
                    sizeof(D_Work_arduinoTestVector));
    
      // S-Function (sfunar_digitalInput): <Root>/RUN_TEST
      pinMode(((uint8_T)2U), INPUT);
    
      // InitializeConditions for Enabled SubSystem: '<Root>/ENABLE_TEST'
      // InitializeConditions for UnitDelay: '<S1>/Unit Delay'
      arduinoTestVector_DWork.UnitDelay_DSTATE = false;
    
      // InitializeConditions for UnitDelay: '<S4>/FixPt Unit Delay2'
      arduinoTestVector_DWork.FixPtUnitDelay2_DSTATE = 1U;
    
      // InitializeConditions for UnitDelay: '<S4>/FixPt Unit Delay1'
      arduinoTestVector_DWork.FixPtUnitDelay1_DSTATE = 0U;
    
      // End of InitializeConditions for SubSystem: '<Root>/ENABLE_TEST'
    
      // S-Function (sfunar_digitalOutput): <Root>/MOTORSHIELD_IN1
      pinMode(((uint8_T)8U), OUTPUT);
    
      // S-Function (sfunar_digitalOutput): <Root>/MOTORSHIELD_IN2
      pinMode(((uint8_T)11U), OUTPUT);
    
      // S-Function (sfunar_analogOutput): <Root>/SPEEDPIN_A
      pinMode(((uint8_T)9U), OUTPUT);
    }
    
    //
    // File trailer for generated code.
    //
    // [EOF]
    //
    
    Весь проект можно скачать здесь.

    Модель, которую я буду использовать для проверки результатов:



    Все модели можно скачать здесь.
    «Открыл и запустил» может не сработать, есть нюансы. С вопросами в личку, или в комментарии.

    Видео




    Результаты


    Вот, что получилось в итоге:



    Синий — это входной сигнал с пределами от -255 до +255. В пересчете на вольты будет примерно от -8,5 до 8,5.
    Зеленый — скорость вращения вала двигателя.

    Видим временную задержку, отсутствие вращения, либо крайне малое вращение при подаче ШИМ менее 25%. Также наблюдаем классический апериодический переходной процесс.

    А вот информация, которая выводится во время проведения эксперимента на дисплей, подключенный к машине реального времени:



    Идентификация


    Одна из подсистем, а именно двигатель, может быть описан следующей передаточной функцией:

    Так нам говорит курс ТАУ, с неё мы и начнем.

    В составе MATLAB есть прекрасный инструмент для идентификации систем — System Identification Toolbox. Он доступен как в виде графического интерфейса, так и в виде набора функций, которые можно использовать в скриптах MATLAB. Рассмотрим сперва работу в графическом интерфейсе.

    Импортируем данные, полученные в ходе эксперимента и тестовое воздействие:


    После импорта нам становятся доступны инструменты предварительной обработки данных. Мы имеем возможность, например, разделить массивы данных на две части — для идентификации и отдельно для верификации. Но это для более сложных случаев, давайте же скорее перейдем к делу!

    Выбираем из выпадающего списка «Estimate» пункт Transfer Function Models.

    Получаем передаточную функцию:


    Давайте сравним поведение полученной функции и системы:


    Синим отображен отклик передаточной функции на исходный тестовый вектор. Видно, что данную функцию можно использовать как модель исходной системы только в режиме старт-стоп. И не удивительно — нелинейное поведение, которое присутствует в системе, не может быть описано таким способом.

    Продвигаемся дальше, используем шаблон модели Хаммерштейна-Винера, которая дает возможность описывать нелинейное поведение системы:



    В качестве входной нелинейности выберем Dead Zone — отсутствие реакции системы на входной сигнал менее определенного порогового значения. Такой тип нелинейности должен взять на себя описание трения спокойствия и влияния постоянных магнитов, которое имеет место в системе.
    Остальные параметры по умолчанию, жмем Estimate.

    Update#1 по просьбе MichaelBorisov:
    Более подробно настройка нелинейной части выглядит так:


    Для случая с Dead Zone все просто — задаем тип и пороговые значения.

    Настройка линейной части позволяет предварительно указать порядок и оценить задержку:


    Несмотря на то, что это «черный ящик» — на практике получение адекватного результата очень зависит от колличества знаний о системе, которые Вы вложили в конфигурацию расчета.
    endOfUpdate#1 по просьбе MichaelBorisov:

    Сравниваем полученный результат с экспериментальными данными:


    Выглядит гораздо лучше! Не идеально — заметно некоторое аномальное поведение, но мы ведь только слегка коснулись идентификации нелинейных систем.

    Теперь нам остается только экспортировать данную модель в Simulink, где мы можем приступить к разработке системы управления. Но об этом в следующем топике!

    Благодарю за внимание, надеюсь было интересно?
    И еще раз благодарю за ответы на небольшой опрос:

    Only registered users can participate in poll. Log in, please.

    На какую тему писать следующий пост? Есть возможность и желание

    • 51.0%Работа с популярным железом в MATLAB/Simulink. LEGO, AR Drone, Arduino, STM32, Raspberry PI, MS Kinect, and more…104
    • 24.5%Работа с профессиональным железом. Машины реального времени Speedgoat, Opal-RT, DSpace, and more…50
    • 58.3%Теория автоматизированного управления (ТАУ), синтез регуляторов, управление «трудными» объектами119
    • 28.4%Генерация кода для встраиваемых систем с помощью Simulink Embeded Coder58
    • 44.1%Физическое моделирование. Механика, электротехника, гидравлика, and more…90
    • 29.4%MATLAB & Robot Operating System (ROS)60
    • 25.5%MATLAB & iPhone/Android sensors52
    • 27.4%Продолжение темы о идентификации систем, «серый» метод — Parameter Estimation56
    • 1.5%Свой вариант в комментариях3
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 33

      +20
      Очень интересно, но ничего не понял)
        +2
        Speedgoat — очень интересно! жду пост
          +1
          Ок, услышано.
            +1
            Мне интересно, что они имели в виду, когда устройство «скоростным козлом» называли?
              +2
              «My deer friend...»
                +2
                Speed goat — это упрощенное название Pronghorn или Вилорога. Я думаю создатели имели в виду быстроту устройства (Вилорог — второе по скорости животное на замле, разгоняется до 70 км/ч)
                  +1
                  Попробуйте в гугл-переводчике перевести с немецкого wolks vagen, дусаю будете тоже удивлены предложенным вариантом)))
                    0
                    Именно wolks vagen или вы все-таки имели в виду Volkswagen (который по правилам немецкого не может писаться раздельно)?
                +2
                Учусь на кафедре систем автоматического управления, такому нас к сожалению не учат) Спасибо, очень интересно.
                  +2
                  Может все еще впереди?))
                  Какой курс?
                    +1
                    Может быть, заканчиваю третий. Было и ТАУ и мат. обеспечение цифровых систем управления, и еще куча всего, но большего чем посмотреть каждое звено в симулинке не было. Хотя вру, собирали звенья на стендах годов 60-х. Это когда куча из 30 студентов отвоевывает работающие провода чтобы проверить работает ли стенд на котором теоретически можно выполнить лабу. Все грустно в общем. Все финансирование идет мимо нашей кафедры.
                      +2
                      Пробуйте самостоятельно. Из инвентаря требуется только комп. Матлаб в помощь — очень мощный инструмент. Тут можно и систему просимулировать во времени, и графики передаточных функций построить, и корни посчитать, и даже синтезировать оптимальный регулятор с помощью очень сложных методов ТОУ, которые даются пользователю практически в виде черного ящика (Contol Systems Toolbox).
                    0
                    нас на пятом учили этому, если мне память не изменяет
                    +2
                    Здорово! Очень интересно. Получается, что вы идентифицировали эту систему как линейную, с добавкой «мертвой зоны», и все? А как же задержка? Она, должно быть, выступает в виде отдельного множителя передаточной функции? А то там и в сотню параметров идентификация не уложилась бы.

                    Было бы интересно также почитать и посмотреть, как вы впоследствии управляете данным объектом после идентификации. Насколько точное управление достигается? Применяется ли теория оптимального управления?

                    И еще, может из практики своей расскажете. Насколько критично при управлении такими объектами то, что их параметры не всегда точно определены или имеют дрейф во времени? Была ли когда-нибудь необходимость создавать адаптивные системы управления, отслеживающие дрейф параметров объекта и т.д.?
                      +2
                      О, какой большой комментарий! Спасибо!

                      Я пока кратко, а через часиков 9 постараюсь более подробно.

                      1. Задержка учтена, гляньте еще на первый случай с передаточной функцией. Согласен, нужно подробней расписать — ждите апдейт.

                      2. Это проще показать, в следующих постах обязательно.

                      3. Адаптивность — капризная вещь! Более популярным методом, я думаю, является метод управления с предсказанием. Model predictive control.
                      Кстати, инструмент, о котором я писал кроме модели идентифицирует еще и шумы и доверительные интервалы парасетров. Эти данные можно применять в построении робастых систем, в том числе и с плывущими параметрами.
                        +1
                        Адаптивность — капризная вещь!

                        Вы просто не умеете ее готовить. :) Ну или не к тем задачам прикладываете.

                        Более популярным методом, я думаю, является метод управления с предсказанием. Model predictive control.

                        Мне кажется, некорректно противопоставлять MPC и Adaptive control, эти подходы решают существенно разные задачи. Так, при MPC, на сколько я помню, базовой гипотезой является знание параметров системы, это позволяет делать предсказания и оптимизацию. При адаптивном же, как и при робастном, управлении параметры считаются неизвестными или известными неточно. Поэтому возможно, например, сочетание подходов: adaptive MPC, robust MPC.
                          +2
                          Вы просто не умеете ее готовить. :) Ну или не к тем задачам прикладываете.

                          Вполне возможно.
                          Адаптивность должна быть подкреплена большим фундаментом знаний о возможном поведении системы и поведении самого алгоритма оптимизации. В противном же случае адаптивный алгоритм может быть опасен на практике.
                          Еще одна проблема на пути адаптивности — это сертификация, которая необходима, например, в гражданской авиации.

                          Предложите пожалуйста пример использования адаптивного алгоритма управления в месте, где он очень кстати.
                          Мне, да и другим читателям, это будет крайне интересно.

                          При адаптивном же, как и при робастном, управлении параметры считаются неизвестными или известными неточно.

                          Тогда применение адаптивности допустимо в системах, которые априори робастые. Чтобы первая же итерация адаптации не привела к аварии.
                          В случае же с MPC адаптация управляющих сигналов производится на модели системы, и только в случае безопасного моделирования ситуации происходит подача их на объект управления.

                          Жду ответ, с нетерпением!
                            +1
                            Адаптивность должна быть подкреплена большим фундаментом знаний о возможном поведении системы и поведении самого алгоритма оптимизации.

                            Возможно, у нас терминологические разночтения. Что вы имеете ввиду под алгоритмом оптимизации при адаптивном управлении? Нет там такого.
                            Кстати, я не думаю, что объем знаний о поведении системы для адаптивного управления должен быть больше, чем для того же MPC. Наверное, даже меньше.

                            Тогда применение адаптивности допустимо в системах, которые априори робастые.

                            Опять, возможно разночтения в терминологии. Что значит «априорно робастные» системы? Вроде как, именно конкретный закон управления делает систему робастной или неробастной. О какой априорности идет речь?

                            Еще одна проблема на пути адаптивности — это сертификация, которая необходима, например, в гражданской авиации.
                            Это хорошее замечание, учитывая что одно из первых реальных использований адаптивных систем — gain scheduling в военной авиации, примерно середина прошлого века.

                            Предложите пожалуйста пример использования адаптивного алгоритма управления в месте, где он очень кстати.

                            Легко. :) Очень много в акустике — компенсация шумов, подавление эха и все остальное в области Active Noise Control. Далее, родственные акустике задачи — активная виброзащита, компенсация возмущений. Управление морскими судами, компенсация качки. Управление впрыском в двигателях внутреннего сгорания. Контроль температуры в автоматизированных теплицах. Это только те задачи, которыми я занимался или которыми занимались мои коллеги, а если смотреть на литературу, то их там сотни. :)
                              0
                              Ах да, совсем забыл. Адаптивные системы еще используются в жестких дисках и в приводах CD. Опять же, для компенсации возмущений. Лично этой проблемой не занимался, но знаю того, кто занимался. Если не путаю, то совместно с WD.
                                +1
                                Так-же, как представленный мною процесс не является в чистом роде «черным ящиком», так и представленные Вами примеры не являются полностью адаптивными.
                                Если уж есть разночтения, то в слове адаптация.

                                gain scheduling — по сути просто переключение между заранее определенными контроллерами для различных операционных точек.
                                Система управления впрыском основана на таблицах калибровок, на основе которых она выбирает уже конкретные параметры тех же ПИД регуляторов. Таблицу мы получаем в процессе калибровки двигателя, либо его статистической модели до реальной эксплуатации.

                                В моем понимании адаптивность — это изменение параметров либо структуры системы управления в зависимости от измеряемых параметров объекта управления либо же качества управления без предопределенности, когда инженер заранее не задает все возможные сценарии развития событий. Машинное обучение + нейронные сети — это адаптивность. В особенности, если обучение происходит во время рабочего режима системы.

                                Мне кажется, некорректно противопоставлять MPC и Adaptive control, эти подходы решают существенно разные задачи.

                                Вот я и имел ввиду, что необходимо использовать scheduled model predictive control. И знать все возможные повороты судьбы)))
                                  0
                                  К остальным примерам, кроме ДВС, вопросов нет? Хорошо. Поясню по gain scheduling и впрыску.

                                  gain scheduling — настолько традиционный пример адаптивной системы, что с него начинаются фундаментальные учебники по адаптивному управлению. Да, это не то, что сейчас на острие научных исследований, но так я и сказал — середина прошлого века, одно из первых практических применений.
                                  калибровочные таблицы для ДВС — это как раз пример gain scheduling. Но в разработке у производителей двигателей находятся более современные адаптивные системы управления впрыском, основанные на непрямой адаптации. Могу говорить про General Motors, где эти системы прошли испытания на Chevrolet Tahoe и еще каком-то.
                        +2
                        Небольшой апдейт по Вашему комментарию в теле топика.
                        Задержка важна, благодарю за уточняющие вопросы!
                        +1
                        Очень интересно было бы почитать про нестандартные регуляторы, не простые ПИД (о них уже есть несколько поучительных статей на хабре), а, например, с моделью, с предсказанием, адаптивные опять же.
                          +2
                          с моделью, с предсказанием


                          Это как раз Model predictive control, о котором я упомянул выше.

                          Идея следующая:

                          1. Есть линейная модель объекта управления, или же линеаризованная для работы в определенной операционной точке.
                          2. Есть ограничения по величинам в системе, которые нельзя нарушать.
                          3. На каждом шаге работы системы выполняется оптимизация, во время которой определяется набор управляющий воздействий, которые не нарушают ограничений и обеспечивают оптимальный переходной процесс. Все это проверяется на модели, и, в случае удачи, подается на актуаторы.
                          4. Проблема с сильно нелинейными системами решается объединением множества таких регуляторов для работы на множестве операционных точек и линеаризизованных моделей системы. Главное вовремя их переключать и обеспечить гладкость управляющих величин во время переключения.

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

                          С помощью такого подхода легко решаются проблемы управления систем с множеством связанных каналов управления и зависимых величин внутри системы. Например, химический реактор — концентрация, объем и температура реагентов часто очень зависят друг от друга, и ПИД здесь не обойтись.
                          +2
                          Спасибо, интересный пост.
                          Но, я почти уверен, что у вас таки серый ящик. Вы, на основе знания (упрощенной) физической модели объекта, задаете порядок системы и отсутствие нулей передаточной функции. В случае с черным ящиком такой информации у вас нет, вы даже порядок системы в общем случае не знаете. Как, например, вы бы провели эксперименты на упомянутом вами химическом реакторе, а потом пытались описать его чисто линейной моделью.
                            0
                            Я согласен с Вами, в апдейте к топику я отметил, что:
                            Несмотря на то, что это «черный ящик» — на практике получение адекватного результата очень зависит от колличества знаний о системе, которые Вы вложили в конфигурацию расчета.


                            Предположим на начальном этапе я ничего не знаю о системе.
                            Но первое суждение о порядке модели я могу сделать основываясь на характере переходного процесса после первого эксперимента. Да оно может быть ложным, но все же. Все последующие итерации да, являтся не чисто «черными».

                            Так что ящик может считаться «идеально черным» только до первого эксперимента с ним.

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

                            Благодарю за хороший комментарий!
                              +1
                              Вы совершенно правы, при идентификации чистого черного ящика часто «перебирают» модели разных порядков, выбирая некоторый подходящий порядок на основе штрафов за размерность, регуляризаций и т.п. Identification Toolbox, например, умеет это делать, все-таки Льюнг не только тулбокс написал, но еще он один из ведущих ученых в области идентификации.
                              Но вы же этого не делаете. Вы точно знаете, что у вас именно двигатель, так что вы ищете параметры конкретной передаточной функции. Это самый что ни на есть серый ящик.

                              PS: Вы по взгляду на переходный процесс отличите 5-ый порядок от 4-го? Наличие двух нулей в системе от трех? :)
                                0
                                О любой системе из реального мира невозможно сказать, что она имеет конкретный порядок ввиду бесконечного множества влияющих факторов и размытой границы понятия системы вцелом. Ну вот маятник, к нему прибавляем воздух, а потом еще магнитное поле Земли, и так до бесконечности.
                                Вопрос в необходимой, а точнее достаточной точности идентификации.

                                Если в итоге реальная система имела один порядок, но при этом адекватно идентифицирована моделью с другим порядком — не вижу в этом ничего зазорного.
                                А в случае ящика предельной черноты мы об этом еще и никогда не узнаем.

                                PS: Вы по взгляду на переходный процесс отличите 5-ый порядок от 4-го? Наличие двух нулей в системе от трех? :)

                                Недостаточно исходных данных))) Взаимное расположение крайне важно!
                                  0
                                  Так ведь идентификация системы по ее достаточно точной, но не избыточной физической модели, — это же и есть серый ящик. Именно это вы и делаете. Хороший ящик, только черным его называть не надо. :)
                            +1
                            Хотелось бы увидеть статьи не только управления сложными объектами, но и опрос таких вот «сложных» объектов (датчиков). Синтез фильтров под конкретные задачи, да и в общем что нибудь про ЦОС.
                              +1
                              ЦОС — это не совсем ТАУ. Где-то у них есть общие методы, передаточные функции, но этим все исчерпывается. Так что, если вас интересует ЦОС — то лучше читать конкретно про ЦОС!
                                0
                                Так мне интересны и ЦОС и ТАУ. Моя специальность связана с автоматизацией, и было очень печально разбираться в курсе ЦОС (когда это понадобилось) которого вообще не было в универе, а теорию ТАУ скручивать в голове с реальными объектами. С техническим оснащением кафедры случай похожий. Крутились как могли.
                              0
                              Ох, спасибо за ностальгию, как раз диплом в былые годы защищал в рамках дисциплины ИДС

                              Only users with full accounts can post comments. Log in, please.