SUMO SUMO Wiki

Wiki カテゴリ&ファイル

目次

SUMO OPC接続

OPC UAサーバーがすでにインストールされ、正しく設定されていることを前提とします。サーバーの設定や実際のプラント機器への接続については、本書の対象範囲外です。

SUMOはOPC UAサーバーに2つの方法で接続できます:

  1. グラフィカルユーザーインターフェースから
  2. dmqclient.pyモジュールを使用してSUMO PythonAPIから

重要な点として、SUMOのOPC機能は現時点ではWindowsでのみ利用可能です。GUIによる接続は今後もWindows専用ですが、Pythonによる接続は将来的にLinuxでも利用可能になる可能性があります。

SUMOアプリケーションからの接続

免責事項:
SUMOのOPCダッシュボードは、テストおよび変数マッピング目的のみのものです!

OPC接続機能に最初に触れるのは、SUMOアプリケーションのAdvanced/OPC Dashboardメニューです。

OPC UAサーバーに接続する前に、いくつかの準備が必要です:

  1. OPC UAサーバーにSUMO関連のデータタグをいくつか作成する(サーバー開発元企業が提供するクライアントアプリケーションを使用)。
  2. sumo.iniファイルで接続を設定する。

SUMO GUI専用データタグ

OPC UAサーバーに以下の新しいデータタグを作成する必要があります:

  1. FastModeMultiplier - リアルタイムシミュレーションを高速化する(デフォルトは0)
  2. MasterSumo - Sumoが時刻の提供元であることを指定する(デフォルトはfalseまたは0)
  3. SumoContinue - 停止したシミュレーションを継続するためのフラグを指定する(デフォルトはfalseまたは0)

次の例では、必要なデータタグの設定方法を示すためにKEPServerEX OPC UAサーバーを使用します。他のOPCサーバー製品を選択することも可能です。

KEPServerEXの設定ツールで、まだ存在しない場合はChannel1という名前の新しいチャネルを追加します。チャネルを作成する際には、プラント機器と互換性のあるいわゆるドライバーを使用できます。この例では、テスト目的に適したSimulatorを選択しました:

1.png
図1 - Channel1プロパティ

Channel1の下にSumoControlという名前の新しいデバイスを次のプロパティで追加します:

2.png
図2 - SumoControlデバイスのプロパティ

SumoControlデバイスの下に必要なデータタグを追加すると、次のようになります:

3.png
図3 - KEPServerEX設定ツールのSUMOデータタグ

SUMOのためのOPC接続設定

通常はユーザーのAppData/Roaming/Dynamita/Sumo24フォルダーにあるsumo.iniファイルに、いくつかのエントリを追加する必要があります(SUMOのインストール方法によって場所は異なる場合があります)。必要なエントリは次の通りです:

OPC_UA_Url                          = opc.tcp://localhost:49320
OPC_FastModeMultiplier              = Channel1.SumoControl.FastModeMultiplier
OPC_MasterSumo                      = Channel1.SumoControl.MasterSumo
OPC_SumoContinue                    = Channel1.SumoControl.SumoContinue
OPC_Time                            = Server.ServerStatus.CurrentTime

OPC_UA_UrlエントリにはOPC UAサーバーのアドレスが含まれています。SUMOはこのアドレスをOPCダッシュボードに入力します。

次の3つのエントリは、前のセクションで紹介したデータタグです。OPC UAサーバー内で異なる構造を使用してもよく、必ずしもこのセットアップに従う必要はありません。ただし、データタグの完全な名前を把握し、sumo.iniに指定する必要があります。

KEPServerEXでは、次の画像のようにデータタグのプロパティのタイトルバーに完全名が表示されます:

4.png
図4 - プロパティのタイトルバーにおけるデータタグの完全名

最後のOPC_Timeエントリは、システムの現在時刻を表すデータタグである必要があります。これはほとんどのOPC UAサーバー実装に存在し、Server.ServerStatus.CurrentTimeという名前です。このシステムタグがサーバーにない場合は、Dynamitaにお問い合わせください(support@dynamita.com)。

システム時刻は、SUMOシミュレーションのリアルタイム同期にとって重要です。

SUMOからサーバーへの接続

sumo.iniの準備が完了したら、SUMOアプリケーションから接続をテストできます。OPCダッシュボードを起動するには、コンパイル済みのプロジェクトが必要です。Tutorial plantの例を開き、AdvancedメニューからOPCダッシュボードを開いてみましょう:

5.png
図5 - OPCダッシュボード; ヘルプポップアップを得るためにiアイコンにマウスをホバー

Connectボタンを押すと、指定したアドレスでアクセス可能なOPC UAサーバーに接続できます。接続に成功すると、次の画像のように、サーバー内のすべてのデータタグがダッシュボードの右側に一覧表示されます:

6.png
図6 - 指定されたサーバーへの接続が成功した; SUMOアプリケーション専用タグが右側に表示される

Disconnectボタンを押すか、SUMOを閉じることで、OPC UAサーバーとの接続を切断できます。SUMOを閉じると、開いている接続は自動的に切断されます。

リアルタイムシミュレーションの設定

OPCサーバーのデータタグに接続する入力パラメータと出力変数のリストを用意する必要があります。

テスト目的では、流入流量を入力パラメータとして、処理水の総リン(total phosphorus)を出力変数として選択できます。お気づきのとおり、SUMOでは入力データをパラメータ、出力データを変数と呼びます。SUMOでは、外部から変更できるのはパラメータ型のデータのみです。

サーバーへの接続をテストすることに加え、ダッシュボードのもう一つの重要な機能は、SUMOとOPC UAサーバーの間にデータマッピングを作成することです。手順は次のとおりです:

SUMOのシンボルにマッピングしたいパラメータと変数について、OPCサーバー側でデータタグを準備する必要があります。この例では、OPCサーバーにPlant_Q(完全名はChannel2.SumoMapping.Plant_Q)とPlant_TP(完全名はChannel2.SumoMapping.Plant_TP)を用意しました。

Qパラメータ(完全名はSumo__Plant__Influent__param__Q)を入力テーブルにドラッグし、次に右側からPlant_Qを同じ行にドラッグしてみましょう。ダッシュボードが完全名をテーブルに自動入力します。

7.png
図7 - Influent/paramノードの下にQが見つかり、SumoMappingの下にPlant_Qがある

次に、TPシンボル(完全名はSumo__Plant__Effluent__TP)を出力テーブルにドラッグし、右側からPlant_TPを同じ行にドラッグしてみましょう。

8.png
図8 - Effluentノードの下にTPが見つかり、SumoMappingの下にPlant_TPがある

Saveを押してマッピングを保存し、Hideボタンでダッシュボードを非表示にします。

リアルタイムシミュレーションの実行

マッピングが設定できたら、シミュレーションをリアルタイムで実行できます。その条件はOPC UAサーバーに接続されていることです。サーバーから切断すると、シミュレーションはフルスピードで実行されます。繰り返しになりますが、OPCダッシュボードは接続のテストと、SUMOシンボルとOPCデータタグ間のマッピング作成のためのものです

StopTimeをデフォルトの1日から1分に、DataCommを5秒に変更します。これは、意味のある時間間隔(5s)でデータの変化を確認するために必要であり、またシミュレーションが「いつまでも」実行されず、リアルタイムで1分間だけ実行されるようにするためです。

さらに、入力パラメータのInfluent Qと出力変数のEffluent TPを含む新しいテーブルを追加します。これにより、パラメータ値が実際にOPC UAサーバーから取得され、出力変数がサーバーに書き込まれることをテストできます。

9.png
図9 - リアルタイムシミュレーションの結果。OPC UAサーバーで流入流量を18000 m3/dに変更しました

出力TPは、次の図のようにOPC UAサーバーに書き込まれ、サーバーの設定アプリケーション(Toolsメニュー)から起動したQuick Client Toolで確認できます。マッピングファイル内で、処理水QにマッピングされたPlant_Qを変更します。次の画像が示すように、Plant_TPデータタグはSUMOから処理水TPの値へと更新されます:

10.png
図10 - OPC UAサーバーのQuick Client Toolでデータタグを更新および確認する

シミュレーションを開始すると、データが5秒ごとに更新され、シミュレーションの実行には1分+5秒かかることが分かります(最後のDataCommを待つためです)。

Python APIからの接続

DTTのPythonモジュールについて詳しく知るには、当社のDTTガイドを参照してください。

SUMO向けのPython開発環境の設定については、当社のガイドを参照してください。

DTTアドオンをインストールすると、SUMOのインストールフォルダーにPythonAPIサブフォルダーが作成され、この例で使用するSUMOモジュールが含まれます。

この例では、MLE-demo.sumoプロジェクトを実行し、OPCダッシュボードで作成したmapping.csvファイルを処理します。マッピングを処理するとは、OPCサーバーから入力パラメータを読み取り、出力変数をOPCサーバーに書き込むことを意味します。

この例では、出力変数をOPCサーバーに書き込むだけで、読み取りは行いません。ソースコードは次の通りです:

import dynamita.dtcontrol as dtcontrol
import dynamita.tool as dtool
import dynamita.dmqclient as DMQ
import time
import os

CURRENT_WORKING_DIR = os.getcwd()
SUMO_PROJECT = os.path.join(CURRENT_WORKING_DIR, "MLE-demo.sumo")
SUMO_STOPTIME = "1minute"
SUMO_DATACOM = "5second"
SUMO_STATE = os.path.join(CURRENT_WORKING_DIR, "sumo_state.xml")
OPC_SERVER_ADDRESS = "opc.tcp://localhost:49320"
OPC_CONFIG = os.path.join(CURRENT_WORKING_DIR, "Sumo.Config.xml")
OPC_MAPPING = os.path.join(CURRENT_WORKING_DIR, "mapping.csv")
TIME_TAG = "_System._Time_Second"
TIME_TICKS = 5
SIM_STEP = TIME_TICKS*dtool.sec
OPC_FREQ : float = 0.1

def sumo_to_opc(dtc):
    if dtc.GUI.is_running() :
        dtc.GUI.core_command_sync(f'save "{SUMO_STATE}"', "530045")
        data = dtool.read_sumocore_xml(SUMO_STATE)
        dtc.OPC.write_mapped_variables(dtc.OPCMapping, lambda x: x.io_type == "Dynamic" and x.io == "O", data)

def main():
    dtc = dtcontrol.DTControl()
    dtc.start_Sumo_GUI(SUMO_PROJECT, SUMO_STOPTIME, SUMO_DATACOM)
    dtc.OPC = DMQ.OPCClient(OPC_SERVER_ADDRESS, OPC_CONFIG)

    dtc.Tick_OPCTag = TIME_TAG
    dtc.Tick_TickToStep = TIME_TICKS
    dtc.SimulationStep = SIM_STEP
    dtc.Tick_CheckFrequency = OPC_FREQ

    dtc.OPCMapping = dtool.read_opc_mapping_csv(f"{OPC_MAPPING}")
    dtc.GUI.onstart(f"load \"{SUMO_STATE}\"; maptoic; set Sumo__LimitTime 1;")
    dtc.Tasks = [dtcontrol.DTTask(action=sumo_to_opc, starttime=TIME_TICKS, looptime=TIME_TICKS)]

    dtc.run()
    dtool.log_print("GUI closed")

main()

説明

まず必要なモジュールをインポートします。SUMOのモジュールは次のとおりです:

インポートの後、SUMOモジュールが必要とする定数をいくつか定義します。ほとんどの定数の意味は明快ですが、一部は説明が必要です:

この例では、シミュレーションは0sから開始し、dtcontrolは実時間で5秒待機してからシミュレーションをシミュレーション時間の5秒目に進め、続いて10s、15sと進めていきます。

20行目には、後でdtcontrolにタスクとして渡されるコールバック関数があります。これはTIME_TICKごとに呼び出されます。

26行目にはメイン関数があります。その中で、dtcという名前のdtcontrolオブジェクトを作成します。これを使って28行目でGUIを起動し、プロジェクト名、ストップタイム、DataComm間隔を渡します。

29行目ではOPC接続オブジェクトを作成し、サーバーアドレスと構成XMLファイルを渡します。

31〜34行目では定数をdtcontrolに渡します。36行目ではマッピングファイルを読み込み、それをdtcontrolに渡します。

37行目ではGUIへのコアコマンドを指定し、38行目では指定した時間間隔で実行されるタスクを設定します。

最後に、40行目でdtcontrolを起動します。

コールバック関数の22行目では、シミュレーションの状態を保存するために、GUIに同期コアコマンドを送信します(つまり、処理が完了するまで待ちます)。その後、その状態を変数に読み込み、マッピングファイルで指定された出力変数の値を検索するために使用します。

24行目では、出力変数をOPCサーバーに書き込みます。

Pythonスクリプトは、SUMOアプリケーション(GUI)を閉じると停止します。