Введение
Однажды меня попросили разработать модель динамики полета АСП (авиационного средства поражения) в отечественном ПО, в среде SimInTech. Причем даже не разработать с нуля, а тупо повторить уже созданную ранее модель в Матлабе (с Симулинком) и любезно выложенную в открытый доступ на гитхабе: https://github.com/JohannesAutenrieb/MissileSimulation
Я подумал - почему бы и нет, можно повторить, ведь в Симинтеке есть практически все требуемые блоки, а если каких нет, то доработаю по образу и подобию. Без погружения в детали, в конце концов так оно и вышло, а итоговый результат был почти идентичен натуральному оригинальному.
В этой модели рассматривается свободный и/или регулируемый полет типового изделия AGARD-B, примерно такой формы:
![Внешний вид Внешний вид](https://habrastorage.org/getpro/habr/upload_files/bc1/e43/b64/bc1e43b64a11636affd0101a69e32101.png)
![AGARD-B AGARD-B](https://habrastorage.org/getpro/habr/upload_files/343/063/e9d/343063e9dce5ad2e68aff636693ca57f.png)
Приведем краткое описание: "AGARD-B представляет собой конфигурацию "корпус-крыло". Все размеры даны в единицах диаметра корпуса "D", поэтому модель может быть изготовлена в любом масштабе, соответствующем конкретной аэродинамической трубе. Тело представляет собой тело вращения длиной 8.5 диаметров, состоящее из цилиндрического сегмента длиной 5.5 диаметра и носовой части длиной 3 диаметра..." Подробнее всё можно найти в сети, например: https://wiki5.ru/wiki/AGARD-B_wind_tunnel_model
Модели
Исходная модель, назовём её прототипом, реализована в программном обеспечении MATLAB/Simulink, и кроме собственно математической модели, содержит набор разных сценариев полета АСП и некоторые из этапов верификации самой модели.
За базовые параметры взяты следующие характеристики:
- диаметр D = 0.150 м,
- длина L = 1.618 м;
- масса M = 30 кг.
Внешний вид прототипа модели АСП и её системы управления представлен на рисунке:
![Внешний вид модели в Simulink Внешний вид модели в Simulink](https://habrastorage.org/getpro/habr/upload_files/128/ade/68c/128ade68cbe10e8fd8ea22da54af5f15.png)
Опуская детали и трудности "копирования" модели из одной среды в другую, это не является предметом данной заметки, в конце концов итоговый результат у меня был подобен оригинальному:
![](https://habrastorage.org/getpro/habr/upload_files/776/a42/36d/776a4236de712a71288558a2a90d1917.png)
Приведу для сравнения еще пару внутренностей субмоделей. Регулятор тангажа:
![Регулятор в СимулинкеСРегулятор в симинтеке Регулятор в СимулинкеСРегулятор в симинтеке](https://habrastorage.org/getpro/habr/upload_files/8b4/847/c61/8b4847c613fdd339440c81ae3bde7598.png)
![Регулятор в Симинтеке Регулятор в Симинтеке](https://habrastorage.org/getpro/habr/upload_files/f1d/041/736/f1d04173624308888975d1fea1def146.png)
Расчёт числа Маха и учет ветра:
![Расчёт числа Маха в Симулинке Расчёт числа Маха в Симулинке](https://habrastorage.org/getpro/habr/upload_files/5d1/ab0/1c7/5d1ab01c73469ab30621c89dc89da6d6.png)
![Расчёт числа Маха в Симинтеке Расчёт числа Маха в Симинтеке](https://habrastorage.org/getpro/habr/upload_files/f58/36c/95c/f5836c95c98572b7df668e13cffa097b.png)
Но мне справедливо возразили - а чем и как докажешь, что твоя модель в Симинтеке считает в точности так же, да ещё и в динамике с произвольными воздействиями, как и исходная модель в Симулинке, которому мы доверяем? Нужна верификация, сказали. Или хотя бы валидация, если за аксиому примем что прототип в Симулинке сделан верно. Чем-то надо подтвердить одинаковость моделей.
Сравнение результатов
Именно этому посвящена данная краткая статья - подходу к сравнению результатов двух расчетов. Наверняка, в теории есть много разных подходов к сравнению, я выбрал метод последовательного тестирования моделей, приведу его краткий алгоритм:
1) Подготавливаем набор тестов, т.е. набор входных воздействий в модель. Желательно чтобы это были не константы и тем более не нули, а изменяющиеся во времени дискретные или непрерывные значения. Потому что при входном сигнале x(t)=0 что sin(2·x) что 2·sin(x) дадут в динамике одинаковый ответ, и формально можно сказать что две модели двойного синуса икс одинаковые, но вот если x(t) будет меняться во времени, то вы увидите разницу, и придется исправить ошибку.
2) Для каждого теста определяемся также с выходными расчетными переменными, которые нас будут интересовать и которые будем сравнивать. У меня это были координаты центар масс ракеты, ориентация, скорости и ускорения по осям, силы и т.д.
3) Задаем двум готовым моделям (в Симулинке и в Симинтеке) одинаковые входные данные. В прототипе, взятом с гитхаба, кстати тоже набор тестов приведен. Мне пришлось его несколько расширить чтобы охватить по возможности все части модели. В моем случае получилось 22 разных сценария, и до 20 расчетных переменных в каждом, которые надо и интересно было сравнить, на рисунке приведены частичные результаты. Физически на диске я имел 22 файла (проекта) в формате Симулинка, и 22 проекта в формате Симинтека. Модель при этом оставалась везде одной и то же, менялись только входные воздействия.
![Результаты расчета в Симулинке Результаты расчета в Симулинке](https://habrastorage.org/getpro/habr/upload_files/86a/893/107/86a893107348b6fb1fffdac987ef00b1.png)
4) Настраиваем одинаковые параметры расчета в обеих средах моделирования, в каждом из тестов. Был выбран самый простой метод интегрирования - метод Эйлера с постоянным шагом, чтобы метод интегрирования не вносил своих погрешностей и отличий в результаты. Также, сравнивались результаты при методах интегрирования Рунге-Кутты 4 порядка (ode4 (Runge-Kutta) в Simulink, RK4 в среде SimInTech). Экспериментально было выяснено что они тоже дают в большинстве случаев одинаковые результаты.
5) Шаг интегрирования задаем равным и там и там, я сравнивал всё с шагом 0.001 с. Конечное время тоже одинаковое, например 2 секунды. Или 100 секунд, зависит от вашей модели и от задачи.
6) Задаем вывод в файл(ы) одинаковых расчетых переменных, то есть результатов расчета.
7) Выполняем расчет в Симулинке.
8) Выполняем расчет в Симинтеке.
9) Сравниваем результаты обеих расчетов, накладывая на одном графике одинаковую расчетную переменную первого и второго расчетов. Также, можно взять разницу между ними и убедиться что она равна нулю на всём интервале моделирования. Либо, если результаты все же отличаются (например из-за особенностей реализации методов интегрирования в разных программных средах), можно посчитать среднеквадратичное отклонение на заданном времени расчета, или еще как-то по-другому оценить рассогласование.
Мне хватило наложения графиков друг на друга и расчета разницы между ними. Приведу внешний вид одного из простых тестов:
![Один из тестов в Симинтеке, с одновременным сравнением с результатами из Симулинка Один из тестов в Симинтеке, с одновременным сравнением с результатами из Симулинка](https://habrastorage.org/getpro/habr/upload_files/925/a0c/cde/925a0ccdecd9fc3c23f743339448b234.png)
А вот один из графиков сравнения, из которого видно что результаты совпадают чуть более чем полностью. Таких графиков я получил сотни, приводить их все здесь не представляется возможным.
![Два результата, наложенные друг на друга на одном графике Два результата, наложенные друг на друга на одном графике](https://habrastorage.org/getpro/habr/upload_files/7d2/3bd/972/7d23bd972dd08a85acd72b9c6555a1ad.png)
![](https://habrastorage.org/getpro/habr/upload_files/a9f/3fe/ddd/a9f3feddd8d63d5f221ae843ab74fb3b.png)
В теории, задача валидации выглядела довольно простой, кроме того что это большой объем чисто технической работы. Но на практике я столкнулся с рядом трудностей.
Опуская трудности переноса самой модели - она всё же не маленькая, более 500 блоков и субмоделей плюс бесконечные уровни вложенности, в самом начале я столкнулся с базовой проблемой: как именно результаты расчета Симулинка выложить в файл, чтобы этот файл потом "понимал" Симинтек? Не являясь сильно опытным пользователем Матлаба с Симулинком, ответа у меня не было. Погуглив и перебрав по возможности все блоки импорта-экспорта в Симулинке, ничего подходящего что выгружало бы результат расчета в один из распространенных текстовых форматов, в Симулинке я не нашёл. Какой-то бинарный только *.mat формат был подходящим, в него Симулинк выгружает временные серии в своём формате. Но как его потом прочитать, оставалось загадкой:
![](https://habrastorage.org/getpro/habr/upload_files/198/104/8da/1981048da19aa174b995f63ee4d5208b.png)
Погуглив тему еще несколько раз, я понял что надо воспользоваться уже языком Матлаба, чтобы перегнать эти временные серии в человеческий (текстовый) формат. Который потом уже в Симинтеке так или иначе я прочитаю. В результате у меня родился такой скрипт для Матлаба (при помощи функции записи матрицы https://www.mathworks.com/help/matlab/ref/writematrix.html):
![Конвертация результатов расчета в CSV-формат Конвертация результатов расчета в CSV-формат](https://habrastorage.org/getpro/habr/upload_files/760/f5a/0b2/760f5a0b29b256efdd46348a8a71bd75.png)
Полученные CSV-файлы по каждой из расчетных переменных, потом я считывал в Симинтеке блоком "Считывание строк из файла". Каждую переменную приходилось записывать в свой файл.
Итого, сначала я прогонял все расчеты в симулинке, потом запускал в работу этот скрипт в Матлабе, а дальше уже полученные CSV-файлы считывал в Симинтеке.
Далее, первые тесты которые я начал гнать на полной модели, выдавали хотя и похожий, но разный результат. А иногда сильно разный. Искать визуально ошибки в схеме на 600 блоков - такое себе занятие. Ничего решительно не нашлось. А делать пошаговый расчет и отлавливать отдельно по сигналам, делать трассировку где и что я выполнил не так, как в прототипе - тоже занятие требующее многих лет жизни и свободного времени и мотивации.
Пришлось решать задачу по частям, и сначала отладить не всю модель, а по составным частям. Сначала регуляторы, потом модель тела с 6-ю степенями свободы, затем матрицы преобразования, составные части расчета аэродинамических коэффициентов. Делая сравнение по составным частям, постепенно все ошибки я нашёл, вычистил их, и смог вернуться к валидации модели АСП в целом.
Далее уже всё шло хорошо, только иногда появлялись новые ошибки в незадействованных предыдущими тестами частях модели, но их уже было относительно легко находить, меняя (зануляя) те или иные входные сигналы и отслеживая в каком именно месте сидит ошибка.
Иногда результаты совпадали "не очень хорошо", и я наблюдал такую бахрому, даже на сведенных к минимуму спорных местах:
![Ненулевая разница Ненулевая разница](https://habrastorage.org/getpro/habr/upload_files/7dc/2a3/0ae/7dc2a30ae255bf0e3fe8a36e43bab17f.png)
Но мы пришли к мнению что это из-за разницы реализации тригонометрических функций в Симулинке и Симинтеке, и всё же это рассогласование (10 в минус 12 степени) очень близко к нулю, и считаем что оно 0.
Заключение
В отечественном ПО SimInTech можно набрать думаю практически любую модель, выполненную в среде MATLAB/Simulink. Наверно, справедливо и обратное утверждение. Есть также конвертор моделей из Симулинка в Симинтек, которым можно пользоваться. Правда он всё равно не отменит ручного труда. В настоящей статье приведен один из подходов к сравнению полученных результатов моделирования в каждом из ПО.
Если публикация вызовет интерес, возможно в будущем более подробно опишу методику переноса модели из одного пакета в другой. Благодарю за внимание!