Práticas recomendadas do conector expansível Modelica

Sep 26 2020

Aqui está um exemplo de funcionamento mínimo de algum uso de conector expansível ocorrendo em meus modelos:

model TestExpandableConnector
  expandable connector ControlBus
    extends Modelica.Icons.SignalBus;
    Real signal1;
    Real signal2;
  end ControlBus;

  ControlBus controlBus;

  // example models to connect signals to
  Modelica.Blocks.Math.Gain gain1;
  Modelica.Blocks.Math.Gain gain2;
  // and so on
equation 
  connect(controlBus.signal1, gain1.u);
  connect(controlBus.signal2, gain2.u);
  // and so on
end TestExpandableConnector;

Isso funciona bem e sem preocupações aqui.

Observe que normalmente este modelo seria criado na camada do diagrama com objetos gráficos e conexões entre o barramento e os componentes (ganhos neste caso).

Embora o exemplo acima seja trivial, em muitos exemplos do mundo real, tenho muitas conexões emergindo desse conector expansível. Isso pode rapidamente se tornar confuso na camada do diagrama e estou tentando aprender / desenvolver algumas das melhores práticas aqui para limpar os diagramas.

Uma opção parece ser usar o bloco RealExpression de uma forma quase equivalente aos elementos From / Goto do Simulink. Por exemplo:

model TestExpandableConnectorRevised
  expandable connector ControlBus
    extends Modelica.Icons.SignalBus;
    Real signal1;
    Real signal2;
  end ControlBus;

  ControlBus controlBus;

  // example models to connect signals to
  Modelica.Blocks.Math.Gain gain1;
  Modelica.Blocks.Math.Gain gain2;
  // and so on

  // using RealEpressions like goto tags
  Modelica.Blocks.Sources.RealExpression realExpression1(y=controlBus.signal1);
  Modelica.Blocks.Sources.RealExpression realExpression2(y=controlBus.signal2);
  // and so on
equation 
  connect(realExpression1.y, gain1.u);
  connect(realExpression2.y, gain2.u);
  // and so on
end TestExpandableConnectorRevised;

Agora, com essa mudança, Dymola reclama que isso é ilegal, pois a causalidade não pode ser determinada. Parece que consigo resolver este último problema 1) adicionando o prefixo "input" às declarações signal1 e signal2 no barramento ou 2) posicionando a declaração para as expressões reais antes da declaração contolBus (esta segunda solução é um pouco estranho para mim).

No geral, estou razoavelmente feliz com essas soluções do ponto de vista de meu diagrama, mas elas também parecem pelo menos um pouco "hackeadas". Meu objetivo básico com esta pergunta é perguntar se essa abordagem é adequada ou se é uma má ideia. Além disso, se houver alguma outra sugestão sobre como lidar com a organização de todas as conexões em um grande modelo (especialmente com conectores expansíveis), sou todo ouvidos. Como um pensamento adicional, parece-me que um recurso "From / Goto" mais dedicado para a linguagem Modelica pode ser muito bom em Modelica, puramente com o propósito de organizar diagramas, mas sendo exatamente equivalente a uma instrução de conexão nos bastidores.

Respostas

4 marco Sep 28 2020 at 16:52

Dymola reclama que

A variável controlBus.signal1 é parte de um conector expansível e só foi usada fora de conectar. Isso não é legal, pois não podemos determinar sua causalidade.

Sua solução revisada funciona, assim que você escrever o sinal em algum lugar usando uma instrução de conexão. Abaixo, reduzi ainda mais seu exemplo para conter apenas signal1. Uma expressão real adicional é usada para definir seu valor.

model TestExpandableConnectorRevised
  expandable connector ControlBus
     Real signal1;
  end ControlBus;

  ControlBus controlBus;
  Modelica.Blocks.Math.Gain gain1;
  Modelica.Blocks.Sources.RealExpression realExpression1(y=controlBus.signal1);

  // Added to write the bus signal
  Modelica.Blocks.Sources.RealExpression realExpression3(y=1);

equation 
  connect(realExpression1.y, gain1.u);

  // Added to write the bus signal
  connect(realExpression3.y, controlBus.signal1);
end TestExpandableConnectorRevised;

Este exemplo compila no modo Dymola pedantic e OpenModelica, então deve funcionar perfeitamente.

Abordagem alternativa usando adaptadores de barramento

Como você pode ver, os conectores expansíveis estão cheios de armadilhas. O problema acima também pode acontecer facilmente se você decidir renomear signal1para mysignalno conector expansível, mas se esquecer de atualizar a instrução de conexão para connect(realExpression3.y, controlBus.mysignal).

Portanto, algumas bibliotecas Modelica decidiram ler e escrever sinais de barramento apenas por meio de adaptadores de barramento. Você deve criar 2 blocos adicionais para cada variável: um para ler e outro para escrever seu valor. É um trabalho muito chato, mas evita o problema acima.

Aqui está um exemplo mínimo para ler e escrever signal1.

package BusAdapters
  partial block BusWriter
    // Dialog allows to set the value of y in the parameter window, like for the real expression
    Modelica.Blocks.Interfaces.RealInput u annotation (Dialog);
    ControlBus controlBus;
  end BusWriter;

  block Write_signal1
    extends BusWriter;
  equation 
    connect(u, controlBus.signal1);
  end Write_signal1;

  partial block BusReader
    Modelica.Blocks.Interfaces.RealOutput y;
    ControlBus controlBus;
  end BusReader;

  block Read_signal1
    extends BusReader;
  equation 
    connect(y, controlBus.signal1);
  end Read_signal1;

  expandable connector ControlBus
    extends Modelica.Icons.SignalBus;
    Real signal1;
  end ControlBus;

  model TestBusConnectors
    ControlBus controlBus;
    Modelica.Blocks.Math.Gain gain1;

    // setting bus variables: using modifiers in write blocks
    Write_signal1 write1(u=sin(time));

    // accessing bus variables part 1: creating instance of reader
    Read_signal1 read1;
  equation 
    // connect all read and write blocks to the same bus instance
    connect(write1.controlBus, controlBus);
    connect(read1.controlBus, controlBus);

    // accessing bus variables part 2: connecting reader with component of interest
    connect(read1.y, gain1.u);
  end TestBusConnectors;
end BusAdapters;

Graficamente, será algo como abaixo. xé escrito diretamente usando os adaptadores de barramento. Para yexpressões reais são usadas, para reduzir o número de linhas em modelos maiores.