* とりあえず動かす
ここでは、とりあえず Eclipse 上で SDLEngine を動作させる手順を説明します。

1. Eclipse のワークスペースに SDLEngine プロジェクトと、SRPCommon プロジェクトがあることを確認して下さい。
2. CORBA Name Server を起動して下さい。SDLEngine/omniNames.bat から起動できます。
  もちろん手動で起動しても問題ありません。
3. SDLEngine/build.xml の idlj.exe を起動できるように JAVA_HOME を設定して下さい。

    <property name="idlj.executable" value="${env.JAVA_HOME}/bin/idlj" />

4. SDLEngine/build.xml を右クリックして、実行→Antビルドを実行して下さい。
5. 問題なくビルドが完了しますと、"SDLEngine Console"というタイトルのウィンドウが表示されます。
6. 以下のスクリプトをコピペで実行して下さい。

  env = rtc.env("localhost", 5005);
  sdlEngine = rtc.local_component("SDLEngine", "SDLEngine");
  myServiceProvider = rtc.local_component("MyServiceBlankProvider", "MyServiceBlankProvider");
  env.get_handles();
  env.connect(env.handles{"MyServiceBlankProvider0.rtc"}.ports{"MyServiceBlankProvider0.MyServiceBlankProvider"}, env.handles{"SDLEngine0.rtc"}.ports{"SDLEngine0.MyServiceConsumer"});
  env.handles{"MyServiceBlankProvider0.rtc"}.activate();
  env.handles{"SDLEngine0.rtc"}.activate();
  myServiceProvider.local_ports{"myservice"}.addListener(new jp.ac.kyutech.SRP.Scripting.ProviderListener() {
    invoke(name, args) {
      print("Method: " + name + " invoked: " + java.util.Arrays.asList(args));
    }
  });
  print(sdlEngine.local_ports{"myservice"}.echo("hello world"));

7. 以下のような表示が見えたら成功です。

  Method: echo invoked: [hello world]

このデモでは、RT コンポーネントを2つ作成し、コンポーネント間での通信が行えていることが確認できます。
SDLEngine のから MyServiceBlankProvider に対して、echo("hello world") のメッセージを送信しています。
そのメッセージを受信した MyServiceBlankProvider がコンソールに送られてきた文字を出力しています。
ここで SDLEngine は Consumer、MyServiceBlankProvider は Provider として振舞います。


* 新しい IDL を SDLEngine に組み込む
IDL ファイルを作成し、それを SDLEngine にサービスポートとして組み込む手順を紹介します。

1. IDL ファイルを SDLEngine/main/idl に配置します。ここでは、MyService.idl とします。
2. build.xml の gen-rtc-sdl-engine ターゲットを修正します。
2.1. Consumer として登録する

		    <arg value="--consumer=MyServiceConsumer:myservice:jp::ac::kyutech::SRP::demo::MyService" />
		    <arg value="--consumer-idl=${main.idl.dir}/MyService.idl" />
		    <arg value="--idl-include=${main.idl.dir}" />

2.2. Provider として登録する

		    <arg value="--provider=MyServiceProvider:myservice:jp::ac::kyutech::SRP::demo::MyService" />
		    <arg value="--provider-idl=${main.idl.dir}/MyService.idl" />
		    <arg value="--idl-include=${main.idl.dir}" />

  なお <arg value > の行は OpenRTM の rtc-template のコマンドライン引数となりますので、そちらを参照して書き換えても問題ありません。
3. Ant の clean ターゲットと rtc.compile ターゲットを起動します。
以上の手順で、SDLEngine に IDL ファイルで定義されたサービスポートを組み込むことができます。



* 新しい RT コンポーネントを SDLEngineに対応させる
ここでは、IDL ファイルから SDLEngine に対応した、空の Provider RT コンポーネントを作成する手順を紹介します。

1. IDL ファイルを SDLEngine/main/idl に配置します。
2. build.xml の gen-rtc-template ターゲットを元に、Ant のターゲットを追加します。
   引数の詳細は OpenRTM のマニュアルを参照して下さい。
   例: Fooサービスを追加する

    <target name="gen-rtc-foo">
        <java classname="jp.go.aist.rtm.rtctemplate.CuiRtcTemplate" >
            <classpath refid="libs.path" />
            <classpath refid="libs.rtctemplate.sdl.path" />
    		<arg value="--output=${rtc.java.dir}" />
            <arg value="--backend=java" />
		    <arg value="--module-name=FooProvider" />
		    <arg value="--module-desc='Foo Provider'" />
		    <arg value="--module-vender='Kyushu Institute of Technology'" />
		    <arg value="--module-category=Provider" />
		    <arg value="--module-comp-type=DataFlowComponent" />
		    <arg value="--module-act-type=SPORADIC" />
		    <arg value="--module-max-inst=1" />
		    <arg value="--service=FooProvider:hogeService:FooService" />
		    <arg value="--service-idl=${main.idl.dir}/Foo.idl" />
        </java>
    </target>

3. build.xml の rtc.all ターゲットに、作成した gen-rtc-* ターゲットを追加します。

    <target name="rtc.all" description="Generate RTComponents code.">
    ....
                <!-- Append rtc generation target -->
                <antcall target="gen-rtc-sdl-engine" />
                <antcall target="gen-rtc-foo" />
                <!-- Append rtc generation target -->
    ....
    </target>

4. Ant の clean ターゲットと rtc.compile ターゲットを起動します。

  $ ant clean rtc.compile

以上の手順で、空の Provider RT Component が作成できます。


* データポートと SDLEngine のデモ
1. 入力した値をデータポートを経由で SDLEngine に送信し、コンソール上で表示するデモです。
2. build.xml の run-console ターゲットを起動して下さい。
  SDLEngine RT Component と SDLConsoleIn RT Component が作成されます。
3. 起動されたコンソールにて、次のスクリプトを動作して下さい。

  env = rtc.env("localhost", 5005);
  sdlEngine = rtc.local_component("SDLEngine", "SDLEngine");
  sdlConsoleIn = rtc.local_component("SDLConsoleIn", "SDLConsoleIn");
  env.get_handles();
  env.connect(env.handles{"SDLEngine0.rtc"}.ports{"SDLEngine0.in"}, env.handles{"SDLConsoleIn0.rtc"}.ports{"SDLConsoleIn0.out"});
  env.handles{"SDLEngine0.rtc"}.activate();
  env.handles{"SDLConsoleIn0.rtc"}.activate();
  sdlEngine.local_ports{"SDLEngine0.in"}.addListener(new jp.ac.kyutech.SRP.Scripting.InPortListener() {
  	dataReceived(event) {
  		value = event.getValue();
  		print("Received: " + value.data + " (" + value.tm.sec + "," + value.tm.nsec + ")");
  	}
  });

4. 次のスクリプトを実行すると、SDLConsoleIn の out データポートに"1"を送信し、

  sdlConsoleIn.local_ports{"SDLConsoleIn0.out"}.put(1);

  結果として、SDLEngine の in データポートで受信し、コンソールに

  Received: 1 (1295249314,340000000)

  を表示します。
  Timed型などで時刻を指定して送信するには、次のように送信し、

  sdlConsoleIn.local_ports{"SDLConsoleIn0.out"}.put(1, new RTC.Time(1234,0));

  Received: 1 (1234,0)

  を表示します。    
5. データポートのイベントを対応したコードを記述することもできます。
  次のようにして、ポートに対してリスナーを登録できます。
  jp.go.aist.rtm.RTC.port.OutPortBase や jp.go.aist.rtm.RTC.port.InPortBase での
  jp.go.aist.rtm.RTC.port.ConnectorDataListenerT の取り扱いと同様です。

  sdlEngine.local_ports{"SDLEngine0.in"}.getPortSupport().addConnectorDataListener(
    jp.go.aist.rtm.RTC.port.ConnectorDataListenerType.ON_RECEIVED,
    new jp.ac.kyutech.SRP.Scripting.ConnectorDataListener() {
      public void operator(jp.go.aist.rtm.RTC.port.ConnectorBase.ConnectorInfo info, RTC.TimedLong data){
        print("on received1");
      }
    });

  その後、SDLConsoleIn の out データポートに"1"を送信すると、

  sdlConsoleIn.local_ports{"SDLConsoleIn0.out"}.put(1);

  コンソールに次のように表示されます。

  on received1

* 新しいデータポートを SDLEngine に組み込む
データポートを SDLEngine に組み込む手順を紹介します。

1. build.xml の gen-rtc-sdl-engine ターゲットを修正します。

    <target name="gen-rtc-sdl-engine">
    ....
				<arg value="--inport=in:RTC::TimedLong" />
				<arg value="--outport=out:RTC::TimedLong" />
    ....
    </target>

1.1 ここでは、in という名の入力ポートと、out という名の出力ポートを作成しています。
1.2 データポートの定義は、サービスポートの定義と重複でき、入力も出力も同時に複数作成できます。
2. Ant の clean ターゲットと rtc.compile ターゲットを起動します。
以上の手順で、SDLEngine に データスポートを組み込むことができます。


* 独自のデータ型のデータポートを SDLEngine に組み込む
独自のデータ型を持つ IDL ファイルを作成し、それを SDLEngine にデータポートとして組み込む手順を紹介します。

1. IDL ファイルを SDLEngine/main/idl に配置します。ここでは、MyData.idl とします。
2. build.xml の gen-rtc-sdl-engine ターゲットを修正します。

		    <arg value="--inport=myDataIn:jp::ac::kyutech::SRP::demo::MyData" />
		    <arg value="--outport=myDataOut:jp::ac::kyutech::SRP::demo::MyData" />

3. Ant の clean ターゲットと rtc.compile ターゲットを起動します。
  以上の手順で、SDLEngine に IDL ファイルで定義されたデータポートを組み込むことができます。
4. 次のスクリプトで、実際に独自データ型が送受信を確認するための用意をします。

  env = rtc.env("localhost", 5005);
  sdlEngine = rtc.local_component("SDLEngine", "SDLEngine");
  env.get_handles();
  env.connect(env.handles{"SDLEngine0.rtc"}.ports{"SDLEngine0.myDataIn"}, env.handles{"SDLEngine0.rtc"}.ports{"SDLEngine0.myDataOut"});
  env.handles{"SDLEngine0.rtc"}.activate();
  sdlEngine.local_ports{"SDLEngine0.myDataIn"}.addListener(new jp.ac.kyutech.SRP.Scripting.InPortListener() {
  	dataReceived(event) {
  		print("Received: " + event.getValue().data1 + "," + event.getValue().data2);
  	}
  });

5. 次のスクリプトを実行すると、SDLEngine の myDataOut データポートにデータを送信し、

  sdlEngine.local_ports{"SDLEngine0.myDataOut"}.put(new jp.ac.kyutech.SRP.demo.MyData(1, "abc"));

  結果として、SDLEngine の myDataIn データポートで受信し、コンソールに結果を表示します。

  Received: 1,abc


* SDLEngine に対応した データポート RT Component の作成
ここでは、データポートに対応するための手順を示します。
1. build.xml の gen-rtc-sdl-console-in ターゲットを元に、Ant のターゲットを追加します。
2. build.xml の rtc.all ターゲットに、作成した gen-rtc-* ターゲットを追加します。

    <target name="rtc.all" description="Generate RTComponents code.">
    ....
                <!-- Append rtc generation target -->
                <antcall target="gen-rtc-sdl-engine" />
                <antcall target="gen-rtc-foo" />
                <!-- Append rtc generation target -->
    ....
    </target>

3. Ant の clean ターゲットと rtc.compile ターゲットを起動します。

  $ ant clean rtc.compile

以上の手順で、データポート RT Component が作成できます。



* GUIを伴わないSDLEngineの起動
GUIのコンソールなしでSDLEngineを起動して、スクリプトを実行する手順です。

1. SDLEngineをコンパイルしておきます。
  $ ant clean rtc.compile

2. build.xml を調整して、読み込むスクリプトを調整します。
  以下での <arg> タグを調整します。
    <target name="run-main" depends="init,rtc.compile" description="Run the BeanShell Console">
        <java classname="jp.ac.kyutech.SRP.Main"  fork="true">
            <classpath refid="libs.path" />
            <classpath location="${main.build.classes.dir}" />
            <classpath location="${rtc.build.classes.dir}" />
            <arg value="doc/test02.txt"/>
        </java>
    </target>
  
3. 必要なコンポーネントの起動などを済ませます。
  テストスクリプトをそのまま使用する場合は、 OpenHRI の portaudiooutput と OpenJTalk 起動しておきます。

4. SDLEngineをGUI無しで起動します。
 $ ant run-main

5. 「test」を発音しているのが聞こえたら成功です。

なお、終了時に警告がでますが、問題ありません。恐らく、OpenRTM-aist-java の実装によるものと思われます。