eSEATでSimpleIO
Simple Wiki Based Contents Management System
ソフトウェア関連 >> RTコンポーネント関連 >> eSEAT_v2.5 >> SEATMLファイルの書き方 >> RTコンポーネントの作成(eSEAT) >> eSEATでSimpleIO

eSEATでSimpleIO

OpenRTM-aistのサンプルであるSimpleIOのConsoleIn及びConsoleOutと同じ機能のSEATMLを作成していきます。
作成するConsoleInとConsoleOutは、以下のようになっています。
ConsoleIn
TimedLong型のデータポート(out)を1つ持っており、コンソールに "Please input number: "を出力し数字の入力待ちを行う、データポートから出力すると同時に入力されたデータを表示します。
ConsoleOut
TimedLong型のデータポート(in)を1つ持っており、データ入力時に受診したデータをコンソールに表示します。

ConsoleIn out (TimeLong)

ConsoleOut in (TimeLong)

ConsoleInの実装

まずは、ひな形のSEATMLファイルをConsoleIn.seatmlといファイルにコピーします。
 # cd ~/work
 # source /usr/local/eSEAT/setup.bash
 # gen_seatml ConsoleIn
次に、適当なエディタでConsoleIn.seatmlを開き、出力データポートの追加を行います。
 <?xml version="1.0" encoding="UTF-8" ?>
 <seatml>
  <general name="ConsoleIn">
    <adaptor name="out" type="rtcout" datatype="TimedLong" />
  </general>

  <state name="main_state">

 </state>

 </seatml>
このコンポーネントでは、単にキーボードからの入力待ちを行いますので、OpenRTM-aistのサンプルにあるConsoleIn.pyと同様に、onExecuteの中にコアロジックを書いていきます。
ここでは、<state>タグの子要素として<onexec>タグでコアロジックを定義します。コアロジック部分は、Pythonスクリプトで定義すると、下記のようになります。
  <state name="main_state">
   <onexec>
     <script sendto="out">
       print("Please input number:", end="")
       val = int(sys.stdin.readline())
       data=TimedLong(Time(0,0), val)
       OpenRTM_aist.setTimestamp(data)
       print("Sending to subscriber: ", data)
       seat.set_result(data)
     </script>
   </onexec>
 </state>
このコードは、ConsoleIn.pyのonExecuteメソッドとほぼ同じです。print関数がPython3の形式になったのと、出力ポートへの関数を記載せずに、sendto属性と set_resultメソッドで書き直されています。eSEATでは、print関数は Python2の時の記法は使うことができません。以前のSEATMLファイルでPython2の記法を使っている場合には、変更する必要があります。
また、adaptorへの出力には、set_resultメソッドを使うようにしていれば、他のadaptorでも同じ記法を使うことができます。
最終的に、ConsoleIn.seatmlは下のようになります。
 <?xml version="1.0" encoding="UTF-8" ?>
 <seatml>
  <general name="ConsoleIn">
    <adaptor name="out" type="rtcout" datatype="TimedLong" />
  </general>

  <state name="main_state">
    <onexec>
     <script sendto="out">
       print("Please input number:", end="")
       val = int(sys.stdin.readline())
       data=TimedLong(Time(0,0), val)
       OpenRTM_aist.setTimestamp(data)
       print("Sending to subscriber: ", data)
       seat.set_result(data)
     </script>
    </onexec>
  </state>

 </seatml>

ConsoleOutの実装

次に、ConsoleOutの実装を行います。まずは、ConsoleInの時と同様に、ひな形をコピーしてConsoleOut.seatmlというファイルを作成します。
 # cd ~/work
 # source /usr/local/eSEAT/setup.bash
 # gen_seatml ConsoleOut
次に、適当なエディタでConsoleOut.seatmlを開き、入力データポートの追加を行います。
 <?xml version="1.0" encoding="UTF-8" ?>
 <seatml>
  <general name="ConsoleOut">
    <adaptor name="in" type="rtcin" datatype="TimedLong" />
  </general>

  <state name="main_state">
 </state>
 </seatml>
ConsoleOutは、入力データポートに受信したデータをコンソールへ出力しますので、コアロジックは、<onexec>タグではなく<rule>タグで作成します。rule>タグでは、データポートからの入力をハンドリングするには、source属性を使います。また、コアロジックをPythonスクリプトで書く場合には、<script>タグをつけることを忘れないでください。
ConsoleOut.pyのonExecuteメソッドの内容を、記載すると、
  <state name="main_state">
   <rule source="in">
     <script>
       data=seat.get_in_data()
       print("Received: ", data)
       print("Received: ", data.data)
       print("TimeStamp", data.tm.sec,"[s] ", data.tm.nsec, "[ns]")  
     </script>
   </rule>
 </state>
となります。このコードで、seat.get_in_dataメソッドは、source属性で指定したadaptorからのデータを得るためのメソッドです。
ここでは、データ型がTimedLongになっていますので、適切にデータアクセスを行ってください。
ROSのSubscriberの場合にも同じようにデータを得ることができます。
最終的にConsoleOut.seatmlは、下記のようになります。
 <?xml version="1.0" encoding="UTF-8" ?>
 <seatml>
  <general name="ConsoleOut">
    <adaptor name="in" type="rtcin" datatype="TimedLong" />
  </general>

  <state name="main_state">
   <rule source="in">
     <script>
       data=seat.get_in_data()
       print("Received: ", data)
       print("Received: ", data.data)
       print("TimeStamp", data.tm.sec,"[s] ", data.tm.usec, "[ns]")  
     </script>
   </rule>
  </state>

 </seatml>

ConsoleIn, ConsoleOutの実行

最後に、ConsoleInとConsoleOutの動作確認を行います。ターミナルを2つ起動し、下記のコマンドを入力します。
ターミナル1:
 # cd ~/work
 # eSEAT ConsoleIn.seatml
ターミナル2:
 # cd ~/work
 # eSEAT ConsoleOut.seatml
次に、RT System Editorまたはrtshellを使用して、2つのコンポーネントの接続を行ってください。ここでは、rtshellでの接続例を示します。
 # rtcon /localhost/ConsoleIn.rtc:out /localhost/ConsoleOut.rtc:in
RTCの接続状況に関しては、下のようにrtcatコマンドで確認することができます。
 $ rtcat -l /localhost/ConsoleIn.rtc
 ConsoleIn.rtc  Inactive
  Category       OpenHRI
  Description    eSEAT (Extened Simple Event Action Transfer)

 Copyright (C) 2009-2014
    Yosuke Matsusaka and Isao Hara
    Intelligent Systems Research Institute,
    National Institute of Advanced Industrial Science and Technology (AIST), Japan
    All rights reserved.
  Licensed under the MIT License (MIT)
  http://www.opensource.org/licenses/MIT
  Instance name  ConsoleIn
  Type name      eSEAT
  Vendor         AIST
  Version        2.5
  Parent         
  Type           Monolithic
 +Extra properties
-Execution Context 0
  State  Running
  Kind   Periodic
  Rate   1000.0
 +Extra properties
-DataOutPort: out
  dataport.data_type          IDL:RTC/TimedLong:1.0
  dataport.dataflow_type      push, pull
  dataport.interface_type     corba_cdr
  dataport.subscription_type  flush, new, periodic
  port.port_type              DataOutPort
 +Connected to  /localhost/ConsoleOut.rtc:in
最後に、2つのコンポーネントをアクティベートします。
 # rtact /localhost/ConsoleIn.rtc
 # rtact /localhost/ConsoleOut.rtc
ここまで行えば、ConsoleInを起動したターミナル1から数字(整数)を入力してください。ターミナル2の方に、入力された数字が出力されれば動作完了です。
下記のコマンドで、ConsoleInとConsoleOutをディアクティベートして、終了して下さい。
 # rtdeact /localhost/ConsoleIn.rtc
 # rtdeact /localhost/ConsoleOut.rtc

 # rtexit /localhost/ConsoleIn.rtc
 # rtexit /localhost/ConsoleOut.rtc
ここまでは、eSEATのRTCのみの確認でしたが、ConsoleIn.pyとConsoleOut.seatml、ConsoleOut.pyとConsoleIn.seatmlの組み合わせでも動作することが確認できればすべて終了です。

資料