Simulinkは、共有メモリを使用してシミュレーション信号の読み取りと送信を行い、制御を実行します

序文

Simulinkは、産業用モデリングおよび制御システムの設計で広く使用されています。産業用制御およびシミュレーションの分野の専門家にとっては使いやすいですが、科学的研究シミュレーションを実行しない顧客にとっては、操作および使用が特に困難です。優れたインタラクティブなエクスペリエンスと画像の視覚化が必要です。共有メモリを使用すると、異なるアプリケーションソフトウェア間のデータ交換が可能になり、Simulinkシミュレーション信号は、3次元アニメーション効果やC#で記述された2次元曲線などの優れた視覚化を備えたソフトウェアなどのサードパーティの視覚化ソフトウェアに転送されます。同時に、サードパーティソフトウェアに視覚化されたコントロールを追加し、共有メモリを使用してMATLAB / Simulinkに転送し、MATLAB / Simulinkの操作を制御することもできます。
このブログ投稿は、Prescanソフトウェアと同様のアニメーション効果を設計するエンジニアにいくつかの参照の意味を与えます。最初の条件は、PrescanソフトウェアがSimulinkプラットフォームに基づいており、Prescanが車両シーンのモデリングとSimulinkプラットフォームでの運転戦略の検証に使用されることです。ソフトウェアSimulinkのシミュレーション信号をサードパーティのソフトウェアに送信し、3Dモデルエンジンを使用してアニメーション表示効果を取得できます。これにより、ソフトウェアの視覚化が大幅に向上します。
このブログで使用されているすべてのプログラムとSimulinkモデルは、記事の最後にある添付ファイルからダウンロードできます。

SimulinkがC関数を呼び出す方法

Simulinkが共有メモリを使用する方法は、共有メモリを操作できるCおよびC ++関数を呼び出すことです。このプロセスを実装するためにSimulinkがC関数を呼び出す方法から始めることができます。SimulinkがC関数を呼び出す主な方法は3つあり
ます。1。最も単純なメソッドは、Simulinkモジュールライブラリで提供されるC Callモジュールを使用します。これはMATLABの2020aバージョンで使用できます(モジュールは将来のバージョンでサポートされると推定されます)が、このメソッドはソースコードを保護できません。モデルの場合がリリースされ、ソースコードも添付する必要があります。
2.ステートフローを使用してC関数を呼び出します。このメソッドはステートマシンモデリングに非常に適しており、C関数を呼び出す必要があります。共有メモリを使用すると、共有メモリが呼び出されたときのメモリの書き込みと読み取りの実行を解決できます。シーケンス、およびstateflowを使用して、より適切な呼び出しシーケンスを構築できます。この方法を使用して共有メモリを操作することを強くお勧めします。
3. S関数を使用すると、共有メモリ関数の動作を完全にカスタマイズできますが、この方法ではCS MEXを作成する必要があります。一般に、C関数に慣れていないユーザーやSモジュールを作成するユーザーは使いにくいです。

Simulinkとアプリケーションプログラムのインタラクティブな実現

ソルバーで設定したステップサイズに応じて、Simulinkはステップごとに1回モデルを実行します。したがって、Simulinkを使用してC関数を呼び出す場合、サンプリングレートが固定され、モデルのサンプリング時間がCを呼び出すという条件の下で関数は継承され、Simulinkがステップサイズを渡すたびに、C関数を繰り返し実行します。プレゼンテーションの場合、デフォルトのSimulinkソルバーは以下の固定ステップサイズです。

1.C関数は共有メモリで動作します

Windowsが提供するメモリスペースを開く関数を使用し、次の関数を呼び出してメモリスペースを開きます。この関数は、MATLABのmスクリプトからも呼び出すことができます。

/**************************************************************************
* Function open_shared_memory()
* Goal  : Creation of a memory-mapped file to share data between 2 processes
* IN    : -
* IN/OUT: -
* OUT   : - Error status in integer coded as following:
*          > 0 => No error occurred and the shared memory has been created
*          > 1 => The process could not create the memory-mapped file object
*          > 2 => The process could not return a pointer to the file view
**************************************************************************/
int open_shared_memory()
{
    
    
  /* Definition of the handle to the memory-mapped file object */
  HANDLE hMappingFile;

  /* Create a new shared memory area if it does not exist yet */
  if (sharedMemoryAddress == NULL)
  {
    
    
    /* Creation of the file mapping object */
    hMappingFile = CreateFileMapping(INVALID_HANDLE_VALUE, // use paging file
      NULL,                 // default security
      PAGE_READWRITE,       // read/write access
      0,                    // maximum object size (high-order DWORD)
      BUFFER_SIZE,          // maximum object size (low-order DWORD)
      SHARED_MEMORY_NAME);  // name of the mapping object
                            /* Exception handling */
    if (hMappingFile == NULL)
    {
    
    
      /* The file mapping object could not have been created */
      _tprintf(TEXT("Could not create the shared memory called: %s\n"), SHARED_MEMORY_NAME);
      return 1;
    }
    /* Create a view of the file in the process address space */
    sharedMemoryAddress = MapViewOfFile(hMappingFile, FILE_MAP_ALL_ACCESS, 0, 0, BUFFER_SIZE);
    /* Exception handling */
    if (sharedMemoryAddress == NULL)
    {
    
    
      /* No pointer to the file view could have been returned */
      _tprintf(TEXT("Could not map the shared memory called: %s\n"), SHARED_MEMORY_NAME);
      /* The process no longer needs access to the file mapping object */
      CloseHandle(hMappingFile);
      return 2;
    }
  }
  /* No error occurred */
  return 0;
}

メモリスペースを開いた後、共有メモリ書き込み機能を使用して、共有メモリに値を書き込むことができます:


void write_register_val(unsigned short address, double val1)
{
    
    
  /* Access the shared memory area */
  if (open_shared_memory() == 0)
  {
    
    
    /* Set the new value in the desired register */
    double * temp = (sharedMemoryAddress + address);
    *temp = val1;
  }
  else
  {
    
    
    getchar();
    exit(EXIT_FAILURE);
  }
}

2.Simulinkとサードパーティのアプリケーションデータ相互作用フレームワーク

C共有メモリ関数(CまたはC ++と同様)を使用し、stateflowを使用して書き込み共有メモリ関数を呼び出します。Simulinkは各ステップで共有メモリ書き込み関数を実行する必要があるため、次回共有メモリ書き込み関数を実行する前、つまりSimulinkが次のステップを実行する前に、サードパーティかどうかを確認する必要があることに注意してください。ソフトウェアアプリケーションが関数を読み取ります。アドレスの値。したがって、書き込み可能フラグビットを使用してSimulinkおよびサードパーティソフトウェアアプリケーションの動作速度を調整するかどうかを設定する必要があります。Simulinkの調整プロセスを次の図に示します。

フロントとバックのデータ転送プロセス

フローチャート1:フロントエンドとバックエンドのデータ相互作用プロセス

まず、フロントエンドとバックエンドの書き込みフラグビットをクリアして、最初のステップを共有メモリに書き込むことができるようにします。メモリに書き込んだ後、書き込みフラグビットを設定できます。次に、3番目のステップで次のSimulink呼び出しを開始します。 -パーティプログラムが読み取らない共有メモリのデータをフェッチするとき、書き込みフラグビットは変更されず、次にstateflowモジュールがstateflowモジュールに対して実行されるときに、データを書き込むことができるかどうかを常に判断します(回避するため)長期の無限ループ待機では、ここに大まかなタイムアウトカウンターが追加されます。つまり、書き込み可能な状態が検出されるたびにカウンターがインクリメントされ、カウンターが特定のデータより大きいと判断して無限ループを終了できます。サードパーティアプリケーションが共有メモリ内のデータを読み取ると、書き込みフラグビットがクリアされます。これにより、Simulinkは無限ループで永久に待機することはありません。
Simulinkは、サードパーティアプリケーションと連携して、各ステップで実行されているSimulinkによって取得されたデータを共有メモリに書き込みます。同時に、サードパーティのアプリケーションは共有メモリ内のデータを順番に読み取ります。

注:Simulinkの実行速度が速すぎたり、サードパーティアプリケーションの読み取り速度が遅いとSimulinkの速度が低下したりしないようにするには、サードパーティアプリケーションが新しいスレッドを開き、バッファーキューを使用してによって送信されたデータを受信する必要があります。 Simulink。このようにして、サードパーティアプリケーションによるデータの表示速度とSimulinkのシミュレーション速度の間の不整合が緩和され、サードパーティアプリケーションはSimulinkシミュレーションの速度によってあまり制限されません。

3.サードパーティアプリケーションがSimulinkを制御します

サードパーティアプリケーションを使用してSimulinkを制御する主な方法は2つあり
ます。1。サードパーティアプリケーションを使用してMATLABが提供するCOMインターフェイスを呼び出し、MATLABを直接制御して制御コマンドを実行します。サードパーティのメソッドを参照してください。 COMインターフェイス関数を呼び出すアプリケーション。私の別のブログ投稿、C#アプリケーションとMATLAB共同プログラミング
MATLABでSimulinkの開始、一時停止、停止、続行、およびステップ操作を制御します。制御コマンドは次のとおりです。

model_name = gcs;
set_param( model_name,'SimulationCommand' ,'start'); % 启动Simulink
set_param( model_name,'SimulationCommand' ,'pause'); % 暂停 Simulink
set_param( model_name,'SimulationCommand' ,'stop');  % 停止 Simulink
set_param( model_name,'SimulationCommand' ,'continue'); % 继续 Simulink
set_param(model_name, 'SimulationCommand', 'step');     % 步进 Simulink

注:この方法では、MATLABが他のMスクリプトを実行できず、MATLABが通常の状態である必要があります
。2 サードパーティアプリケーションの共有メモリを使用して実行フラグを記述し、MATLABスクリプトの実行を制御してから制御します。 MATLABスクリプトを介したSimulinkの操作。この方法は、MATLABを最も包括的に制御するため、推奨されます。
ここでは、MATLABとSimulink間の操作メカニズムを紹介する必要があります。Simulinkが実行されている場合、MATLABはコマンドウィンドウで制御命令を実行できます。したがって、最初の方法を使用してSimulinkを制御できます。MATLABがスクリプト関数を実行すると、Simulinkは実行できず、待機状態になります。スクリプトの実行が一時停止されている場合にのみ、Simulinkは実行を継続できます。
サードパーティのアプリケーションは共有メモリを介してMATLABを制御するため、MATLABは共有メモリフラグのステータスを監視する必要があります。これには、MATLABがこのプロセスを実行するために常にMスクリプト関数を実行する必要があります。これにより、Simulinkが常にブロックされ、シミュレーションできなくなります。したがって、Simulinkモデルを実行する必要がある場合、M関数は、Simulink操作の共有メモリフラグビットを監視している間、一時的に一時停止する必要があります。以下では、このメソッドを使用してMATLAB / Simulinkを制御します。

4.実施方法

フォアグラウンド制御のバックグラウンドSimulinkとシミュレーションプログラムの実行プロセスを2に示します。このプロセスは、Mスクリプトの実行プロセスです。主な詳細部分は、Simulinkの相互制御部分です。前処理が完了すると、main関数はモデルシミュレーションを呼び出します。モデルがフォアグラウンドでシミュレーションを開始できるかどうかを判断するのは初めてです。フロントステーションでシミュレーションが許可されていない場合、バックグラウンドmのメインプログラムは一時停止し、フォアグラウンドでシミュレーションが許可されるまで待機します。フロントステーションでバックグラウンドモデルシミュレーションを有効にすると、バックグラウンドがSimulinkシミュレーション操作を制御し、Mファイルが一時停止してSimulinkの実行を待機します。Mファイルの一時停止が終了すると、フォアグラウンドの制御コマンドが再度検出され、フォアグラウンドの制御コマンドが受信されます。このようにして、Mファイルはフォアグラウンドの制御命令を受け入れることができますが、Simulinkを実行してフォアグラウンドの制御を受け入れることもできます。

ここに画像の説明を挿入

フローチャート2:フォアグラウンド制御とバックグラウンド操作プロセス

図からわかるように、バックグラウンド動作を制御するためのフォアグラウンドの制御命令は、共有メモリのフラグビットによって完了します。Simulinkの動作を制御するためのフォアグラウンドのコマンドには、開始、ステップ、一時停止、続行、および終了が含まれます。
注:フロントステーションが高速で実行されている場合、Simulinkの一時停止時にMファイルが実行され、Simulinkの実行が完了した後にモデル実行完了フラグが設定されるため、Mファイルは一時停止状態のままであり、フロントデスクは実行完了ステータスを受け取ります。モデル実行完了フラグが設定されます。この時点で、Mファイルの一時停止が終了し、Mファイルがまだ実行中であるというエラー状態が発生します。したがって、この状況を回避するために、モデル操作の完了から次のモデル操作の命令までの時間は、フォアグラウンドでのMファイルの一時停止の時間間隔よりも長くなります。

別館

おすすめ

転載: blog.csdn.net/qq_36320710/article/details/112008430