FlexSimのXML
概要
FlexSimは、モデル、ライブラリ、ツリーファイルをXML形式で保存します。この機能をモデル開発で使用すると、次のように多くのメリットがあります。
- XMLはASCII/テキストベースの形式であるため、モデル開発の管理におけるSubversion、CVS、Microsoft Visual SourceSafe、gitなどのコンテンツ管理とバージョン管理ソフトウェア使用の有用性が向上します。これらのシステムは、モデルやプロジェクトの変更履歴を自動的にトラッキングし、ASCII/テキストベースのファイルの場合は、ファイルごとに行単位の変更ログを表示したり、必要に応じて行項目の変更を元に戻したりできます。
- バージョン管理システムを使用することによって、より効率のよい方法を使用して異なるモデラーで同時にモデルを開発できるようになります。1つのモデラーによるモデルの変更を個別のファイルに保存して、手動でマスターモデルに読み込む必要はありません。XML形式に保存すると、1つのモデラーがモデルの一部で作業している場合、モデルファイルのその部分だけが保存時に変更されるため、モデラーがバージョン管理システムのリポジトリに変更を通知すると、他のモデラーは自動的にそれらの変更点を統合できます。2つのモデラーがモデルの同じ部分を変更する競合がある場合、バージョン管理システムには、XMLファイルに競合が発生した箇所を表示し、手動で簡単に競合を解決できるツールがあります。
- FlexSimには、1つのモデルを複数のXMLファイルに分散する機能も追加されています。これにより、バージョン管理システムでのモデル開発の管理方法が制御され、競合解消がさらに簡単になります。
- また、分布保存メカニズムにより、FlexSimの自動制御が可能になります。モデルの小さな部分を別々のXMLファイルに保存することで、FlexSim外に1つ以上のXMLファイルが自動生成されるため、異なるシナリオを実行する際にモデルの構成を変更できるようになります。
シンプルモデルを構築
まず、ソース、キュー、プロセッサ、シンクを含む単純なサンプルモデルを作成します。
XML形式で保存
モデルを保存し、保存ダイアログボックスの下部にあるドロップダウンから「FlexSim XML」を選択します。モデルを「PostOfficeXML.fsx」として保存します。
これで、ファイルをFlexSimのXML形式で保存しました。メモ帳、Visual Studio、メモ帳++、EditPlusなどの通常のテキストエディタでファイルを表示できます。
XMLファイルの自動変更を行う予定がない限り、ファイル形式の詳細をすべて把握しておく必要はありません。簡単に言えば、FlexSim XMLのプライマリタグは<node>タグで、FlexSimのノードを表します。ノードの名前は<name>タグで記述され、ノードのデータ(該当する場合)は<data>タグで記述されます。自動変更を行う予定があり、xml形式の詳細な定義が必要な場合は、FlexSimのxmlスキーマを参照してください。
バージョン管理ユーティリティ
XMLフォーマットを使用するメリットをよりわかりやすく説明するため、バージョン管理システムで行うことのできる操作をいくつかご紹介します。FlexSimでは、Gitと各種クライアント側UIツール(Fork、Git Extensions、Sourcetreeなど)を使用しています。バージョン管理システムのインストールと設定の詳細については、このチュートリアルの対象外です。インストールとセットアップのヘルプについては、ホームページでご確認いただけます。このチュートリアルでは、モデルが保存されると、そのモデルに対してリポジトリが設定されると仮定します。
TortoiseSVNやTortoiseHgなど、Windowsエクスプローラーに統合されたバージョン管理システムを使用すると、未変更のファイルは緑色のアイコンとともに表示されます。このアイコンは、コピーが「クリーン」であること、つまり前回のチェックイン以降変更が加えられていないことを示します。
ここで、キューを別の場所に移動してモデルを再度保存するなど、モデルを少し変更したとします。
一旦保存すると、ファイルのアイコンが赤い記号に変わります。つまり、ファイルが「ダーティ」であるか、前回のチェックイン以降に変更されたことを意味します。また、ファイルを右クリックして「差分」オペレーションを選択すると、変更内容を確認できます。これにより、ファイルの現在のコピーと、最後にチェックインした際のバージョンとの差分比較ができます。
各種バージョン管理ソフトウェア製品には簡単な差分ユーティリティが備わっていますが、WinMergeやkdiff3などのサードパーティの比較ツールを使用するように設定することもできます。
差分ツールを使用すると、モデルが変更された場所、つまりspatialx属性とspatialy属性を確認できます。これらの変更を適用しない場合は、差分ツールでラインアイテムの変更点を戻すことができます。
分布保存
次に、複数のファイルにモデルを配布します。これを行うには、「FlexSim File Map」ファイルを作成します。これは拡張子が.ffmのxmlファイルです。モデルの.fsxファイルと同じディレクトリに配置する必要があります。拡張子を除き、.fsxファイルと同じ名前を付ける必要があります。では、ファイルを作成しましょう。分布ファイルを置くサブディレクトリを作成します。
PostOfficeXML.ffmをテキストエディタで編集します。まず、node model/Tools/Workspaceを別のファイルに配置します。バージョン管理を使用している場合は、常にこれを行うことをお勧めします。node model/Tools/Workspaceには、モデルで開いているすべてのウィンドウが保存されるため、モデルの編集中に開いているウィンドウを変更または再配置すると、モデルファイルが変更されます。バージョン管理の場合、これはトラッキングが必要ない静的なものであることが多いため、ノードを別のファイルに保存しておき、そのファイルをバージョン管理にチェックインすることはほとんどありません。次のコードを指定します。
<?xml version="1.0" encoding="UTF-8"?>
<flexsim-file-map version="1">
<map-node path="/Tools/Workspace" file="distributedfiles\windows.fsx" file-map-method="single-node"/>
</flexsim-file-map>
ファイルマップを保存してから、FlexSimに戻ります。ポストオフィスモデルを「PostOfficeXML.fsx」という名前で再度保存します。distributed filesディレクトリを確認します。windows.fsxという名前の新しいxmlファイルが含まれていることがわかります。このxmlには、node model/Tools/Workspaceの定義が含まれています。モデルとのやり取りはすべて同じです(つまり、FlexSimからメインXMLモデルファイルをロードして保存するだけですが、モデルは複数のファイルに分散されます)。
ファイルマップでは、主要なドキュメント要素は<flexsim-file-map>タグです。主要なドキュメント要素の中には、任意の数の<map-node>要素を入れる必要があります。各<map-node>要素には、パス属性、ファイル属性、ファイルマップメソッド属性が必要です。パス属性には、保存されているメインノードから分散ファイルに保存されるノードまでのパスを指定します。ファイル属性は、保存されたモデルファイルから保存する分散ファイルへの相対パスを指定します。file-map-methodには、「single-node」または「split-points」のいずれかの値が必要です。この場合、「single-node」は、すべてのワークスペースノードをwindows.fsxに保存することを意味します。
次に、「split-points」メソッドの例を見てみましょう。ツールフォルダを1つのファイルに、ソースとキューを別のファイルに、プロセッサとシンクを3つ目のファイルに保存するとします。これを行うには、別の<map-node>要素をファイルマップに追加します。
<?xml version="1.0" encoding="UTF-8"?>
<flexsim-file-map version="1">
<map-node path="/Tools/Workspace" file="distributedfiles\windows.fsx" file-map-method="single-node"/>
<map-node path="" file="distributedfiles\Tools.fsx" file-map-method="split-points">
<split-point name="Source1" file="distributedfiles\Source_Queue.fsx"/>
<split-point name="Processor3" file="distributedfiles\Processor_Sink.fsx"/>
</map-node>
</flexsim-file-map>
ここでファイルを保存し、FlexSimモデルを保存します。distributedfilesディレクトリに新しく作成されたファイルが表示されます。
<map-node>要素が「split-points」メソッドを使用する場合は、<split-point>サブ要素を持つことができます。各split-pointには名前が必要で、マップノードの定義済みノード内のノードの名前を定義する名前と、保存するファイルを定義するファイル属性が必要です。map-nodeにはpath=""属性があります。つまり、ルートノードまたはモデル自体に適用されます。map-nodeのファイル属性は、最初に使用するファイルを定義します。この設定では、モデルの「Source1」という名前のノードまでのすべてのサブノード(ただしSource1を除く)を「distributedfiles\Tools.fsx」ファイルに保存し、Source1から「Processor3」という名前のノードまでをすべて(ただしProcessor3を除く)を「distributedfiles\Source_Queue.fsx」に保存し、Processor3から最後までのすべてを「distributedfiles\Processor_Sink.fsx」保存するようにFlexSimに指示します。
分布の理由
モデルを複数のファイルに分散させる主な理由は、バージョン管理のためです。これにより、どのファイル、したがってツリーのどの部分が変更されたかを見て、モデルで変更した内容を簡単に確認できます。モデルの一部を誤って変更した場合でも、それを簡単に確認でき、必要に応じてその変更を元に戻すことができます。複数のモデラーがモデルを開発しているとき、基本的に1つのモデラーをモデルツリーの1つの部分に制約でき、ツリーのその部分を特定のファイルに関連付けることによって、別の開発者による変更をより簡単に統合できるため統合による競合を軽減できるほか、手動での統合も簡単になります。
接続を保存する
XML保存を使用する場合に理解すべき重要なことは、接続がどのようにXMLファイルにエンコードされるかです。接続(つまり、ツリー内の他のノードを指しているノード)をエンコードする場合は、ルート保存ポイントに相対するターゲットノードへの一意の名前付きパスがこのファイルに保存されるパスになります。
これは、モデル内のオブジェクトにどのような名前を付けるかに影響する可能性があります。同じ名前のオブジェクトが複数存在する場合は、FlexSimが特殊な「~」チルダ記号を使用して一意のパスを解決します。たとえば、モデル内に「Queue」という名前の複数のオブジェクトが存在する場合、モデルに相対する1つ目のモデルの一意のパスは/Queueです。ただし、2つ目のオブジェクトの一意のパスは/Queue~2、3つ目のオブジェクトの一意のパスは/Queue~3といった具合です。
接続は一意のパスをエンコードするため、同じ名前の2つ目以降のオブジェクトの場合は、入力ポート、出力ポート、センターポートなどのそのオブジェクトに対するすべての接続が/Queue~2をパスの一部として使用してXMLにエンコードされます。これは望ましいことですが、特に、モデル差分や他者の変更の一括マージに関するソースコントロールに重要な影響を及ぼす可能性があります。モデル内の「Queue」という名前の1つ目のオブジェクトを削除した場合やただ単にその名前を「MyQueue」に変更した場合は、「Queue」という名前の他のすべてのオブジェクトのxml保存済みパスが変更されます。過去に/Queue~2を参照していたすべての接続が/Queueを参照するようになり、過去に/Queue~3を参照していたすべての接続が/Queue~2を参照するようになるといった具合です。つまり、単一のオブジェクトを削除するだけで、モデル上のすべてのxml変更が実施されます。第一に、これにより、必要な差分よりもコミットする必要のある差分の方が多くなります。第二に、他のユーザーが同時にxmlファイルの同じ部分に影響する変更を加えた場合に潜在的なマージの問題が発生します。このようなマージの競合は、多くの場合、標準のマージツールを使用した解決を非常に困難にします。
これらを考慮したうえで、モデル内の同じツリーレイヤーに存在するオブジェクトの名前は一意にすることを強くお勧めします。そうすることにより、モデル変更によって生成される差分を最小限に抑え、複数のモデラーからの作品をより簡単にマージできます。