Можно ли построить "условный" FMU с помощью Modelica?

У меня есть приложение, в котором я использую Dymola в качестве среды разработки, но буду экспортировать модели в форме FMU для использования в другом приложении. Системы, которые я моделирую, имеют взаимозаменяемые компоненты, что делает их идеальными для моделирования в Modelica. Но я не уверен, что смогу использовать эту возможность, когда хочу экспортировать модели в форме FMU.

Рассмотрим очень простой пакет ниже. Цель пакета - определить две очень простые модели и позволить пользователю выбирать между возможными моделями при выполнении модели. Хотя это легко сделать в Modelica IDE, мне нужны аналогичные возможности в FMU.

Частичная модель определяет модель, где y = p0 + p1*x. Две расширенные модели просто присваивают разные значения параметрам p0 и p1. Наконец, TestModel добавляет параметр с именем modelIndex, который используется в условных выражениях, определяющих два возможных типа модели. В Dymola это прекрасно работает, так как пользователь может легко установить значение параметра modelIndex. Я пытаюсь выяснить, возможно ли это сделать через FMU, сделав modelIndex входом в FMU. Но компиляция не удалась, если я установил аннотацию Evaluate = false для переменной modelIndex. Заявленная ошибка: "Текущая версия транслятора Modelica может обрабатывать только условные компоненты с фиксированным условием... Все переменные, используемые в условии условного объявления, должны быть объявлены как константы или параметры".

Если кто-то может помочь дать рекомендации о том, как создать условную FMU, он будет очень признателен. Этот простой пример используется только для демонстрации проблемы. Моделируемая истинная система имеет 4-5 основных компонентов, каждый из которых имеет более 5 возможных различных моделей, что дает большой набор возможных перестановок. Простой пакетный экспорт всех конфигураций, скорее всего, невозможен.

Спасибо! Джастин

package ConfigurableModel 
  "Package to test whether or not models can be configured by external inputs"
  partial model partialModel 
    "Partial model used to control selectable options in Dymola"

    Modelica.Blocks.Interfaces.RealInput x(start = 1) "input value";
    Modelica.Blocks.Interfaces.RealOutput y "output value";

    parameter Real p0 = 0;
    parameter Real p1 = 0;

  equation 
    y = p0 + p1*x;
      annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
      coordinateSystem(preserveAspectRatio=false)));
  end partialModel;

  model linearModel_NoOffset "Linear model with no offset"
    extends partialModel(p0 = 0, p1 = 1);
  end linearModel_NoOffset;

  model linearModel_Offset "Linear model with offset"
    extends partialModel(p0=1, p1=1);
  end linearModel_Offset;

  model TestModel "Model to test configurability"
    // parameter Integer modelIndex = 2 "1 = linear_NoOffset, 2 = linear_Offset" annotation(Evaluate=false);

    parameter Integer modelIndex = 2 "1 = linear_NoOffset, 2 = linear_Offset";

    // Conditional instances, only one model is created based upon value of modelIndex
    linearModel_NoOffset linear_NoOffset if modelIndex == 1;
    linearModel_Offset linear_Offset if modelIndex == 2;

    // Input and output blocks
    Modelica.Blocks.Sources.Constant xMaster(k=1) annotation (Placement(transformation(extent={{-100,-10},{-80,10}})));
    Modelica.Blocks.Interfaces.RealOutput yMaster annotation (Placement(transformation(extent={{100,-10},{120,10}})));

  equation 
    // Note that only the connections for the components that exist will be used

    // Connect input to each model instance
    connect(xMaster.y, linear_NoOffset.x);
    connect(xMaster.y, linear_Offset.x);

    // Connect output to each model instance
    connect(yMaster, linear_NoOffset.y);
    connect(yMaster, linear_Offset.y);

      annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
      coordinateSystem(preserveAspectRatio=false)));
  end TestModel;
    annotation (uses(Modelica(version="3.2.1")));
end ConfigurableModel;

2 ответа

Похоже, что ваша проблема может быть решена с использованием подхода Elmqvist (2014), хотя с тех пор я больше ничего не слышал по этому вопросу. Я не уверен, был ли какой-либо автоматический подход добавлен в Dymola, но вы могли бы попытаться смоделировать переключение ваших моделей явно.

Насколько я понимаю, это невозможно напрямую с FMI. Объектно-ориентированные функции Modelica, такие как условная реализация, обрабатываются во время символической обработки Modelica перед генерацией C-кода, являющегося частью FMU (в виде C-кода или в скомпилированной форме). Посредством условной реализации многие свойства экспортируемых FMU могут быть изменены (например, иметь различное количество состояний). Таким образом, вы не можете иметь один файл modeldescription.xml в FMU, описывающий свойства FMU. Вы могли бы рассмотреть возможность разделения вашей модели на несколько FMU и иметь дело с изменчивостью подсистем, заменяя некоторые из них. Однако это может привести к более сложной числовой задаче, чем с исходной общей моделью Modelica, так как никакая оптимизация общей модели не может быть выполнена, как компилятором Modelica для всей модели. Одним из преимуществ вашего примера является то, что ваша частичная модель уже имеет причинно-следственные интерфейсы (RealInput и RealOutput). Обходной путь, чтобы приблизиться к вашему намеченному решению, может заключаться в том, что вы включаете обе подмодели linear_NoOffset и linear_Offset (без "if modelIndex == xy") в вашей модели, включите переключатели, запускаемые modelIndex, чтобы переключаться между сигналами на и от двух подмоделей. Может привести к некоторым вычислительным затратам, поскольку обе подмодели присутствуют и оцениваются.

Другие вопросы по тегам