eSEATでSimpleIO
OpenRTM-aistのサンプルであるSimpleIOのConsoleIn及びConsoleOutと同じ機能のSEATMLを作成していきます。
作成するConsoleInとConsoleOutは、以下のようになっています。
- ConsoleIn
- TimedLong型のデータポート(out)を1つ持っており、コンソールに "Please input number: "を出力し数字の入力待ちを行う、データポートから出力すると同時に入力されたデータを表示します。
- ConsoleOut
- TimedLong型のデータポート(in)を1つ持っており、データ入力時に受診したデータをコンソールに表示します。
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になっていますので、適切にデータアクセスを行ってください。
ここでは、データ型が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の組み合わせでも動作することが確認できればすべて終了です。
資料