Перейти к содержанию

Создание модели в Simulink

В этом уроке мы перенесём матрицы пространства состояний \(A\), \(B\), \(C\), \(D\) из MATLAB-скрипта (см. Урок 4) в Simulink-схему, получим работающую динамическую модель и подготовим её для последующей кодогенерации в DLL/SO для Python (см. Урок 6).

MATLAB-скрипт — удобный язык вычислений, но не симулятор реального времени. Simulink даёт несколько важных вещей, которых нет в чистом скрипте:

  • Дискретные интеграторы по времени (фиксированный или переменный шаг) с автоматической синхронизацией всех блоков.
  • Графический интерфейс, в котором структура объекта управления видна в виде блок-схемы — удобно для отладки и для документирования.
  • Кодогенерация Embedded Coder — превращает модель в C/C++ с фиксированным dt, готовый к встраиванию в DLL/SO для вызова из Python. Без этого шага Python-обёртки ctypes (Урок 6) построить нельзя.

ОУ в ПО Simulink

Для создания ОУ в Simulink выполните:

  1. В рабочее поле добавьте элементы из библиотеки Simulink:
  2. Simulink/Continuous/State-Space — реализация уравнений \(\dot{x} = Ax + Bu\), \(y = Cx + Du\) в одном блоке. Это и есть ваш ОУ.
  3. Simulink/Sources/Digital Clock — источник модельного времени; удобен для логирования и для блоков, явно зависящих от \(t\).
  4. Simulink/Commonly Used Blocks/In1 — внешний вход модели (вектор управления \(u\)). Embedded Coder при кодогенерации преобразует его в поле структуры ExtU.
  5. Simulink/Commonly Used Blocks/Out1 — внешний выход модели (вектор \(y\)). При кодогенерации становится полем ExtY.
  6. Переименуйте блоки In1/Out1 в осмысленные имена сигналов — например, ref_signal для входа, u/w/q/theta для компонент выхода. Эти имена один к одному попадут в C-структуры и в обёртку ctypes на стороне Python (Урок 6).
  7. В блоке State-Space задайте параметры — удобнее всего ссылками на переменные рабочего пространства MATLAB:
  8. A: имя переменной матрицы состояния (заполняется из скрипта Урока 4).
  9. B: матрица управления.
  10. C, D: матрицы наблюдения и проброса. Если все компоненты состояния доступны как выход, обычно \(C = I\) и \(D = 0\).
  11. Initial conditions: начальный вектор \(x_0\) (часто zeros).

Блок State-Space

Параметры расчёта

Перед запуском зайдите в Simulation → Model Configuration Parameters и задайте:

  • Solver type: Fixed-step (для совместимости с кодогенерацией — переменный шаг Embedded Coder не поддерживает).
  • Fixed-step size: тот же dt, что вы используете в Python-среде (например, 0.01 с для F-16, 0.02 с для B747).
  • Stop time: длительность симуляции; влияет только на запуск из Simulink, при кодогенерации шаг управляется внешним циклом.
  • Solver: ode4 (Runge-Kutta) — хороший компромисс между точностью и предсказуемостью для линейных и слабо нелинейных систем.

Согласование dt

Если dt в Simulink и в Python-обёртке (Урок 6) различаются, динамика будет искажена: дискретные матрицы \(A_d, B_d\) зависят от dt. Лучшая практика — задать dt константой в MATLAB-скрипте и ссылаться на неё и в Simulink-параметрах, и в Python-коде.

Проверка перед кодогенерацией

Запустите симуляцию из Simulink (Ctrl+T) с тестовым входом — например, ступенчатым через блок Step — и убедитесь, что:

  • Графики выходов Out1 совпадают с тем, что даёт прямой расчёт \(y = Ce^{At}x_0 + \int_0^t Ce^{A(t-\tau)}Bu(\tau)\,d\tau\) в MATLAB.
  • Нет предупреждений типа Algebraic loop или Sample time mismatch.
  • Размерности сигналов на портах согласованы с матрицами A, B, C, D.

После этого можно переходить к Уроку 6 — кодогенерации Embedded Coder и сборке DLL/SO для Python.