Project

General

Profile

機能 #3407

⑧ ダイレクトデータポート接続機能

Added by n-ando almost 6 years ago. Updated about 4 years ago.

Status:
終了
Priority:
通常
Assignee:
Start date:
12/22/2015
Due date:
03/25/2016
% Done:

100%

Estimated time:
30.00 h

Description

同一プロセス内のデータポート接続において、OutPortがInPortの変数に直接書き込む(push型)、またはInPortがOutPortの変数を直接読む(Pull型)形でデータ転送をする方式を実装すること。

test_DirectPort.py (2.05 KB) test_DirectPort.py miyamoto, 01/14/2016 10:45 PM

Associated revisions

Revision 637 (diff)
Added by miyamoto over 5 years ago

[compat,bugfix,->RELENG_1_2] bug fix. refs #3407

Revision 639 (diff)
Added by miyamoto over 5 years ago

[incompat,new_func,new_file,->RELENG_1_2] Direct data put functionality between data ports has been implemented. refs #3407

Revision 649 (diff)
Added by miyamoto over 5 years ago

[compat,bugfix,->RELENG_1_2] bug fix. refs #3407

Revision 650 (diff)
Added by miyamoto over 5 years ago

[incompat,new_func,new_file,->RELENG_1_2] Direct data put functionality between data ports has been implemented. refs #3407

Revision 669 (diff)
Added by miyamoto over 5 years ago

[incompat,bugfix,func,->RELENG_1_2] bug fix. refs #3407

History

#1 Updated by miyamoto almost 6 years ago

  • Due date set to 03/25/2016
  • Assignee set to miyamoto
  • Target version set to RELEASE_1_2_0
  • % Done changed from 0 to 80
  • Estimated time set to 30.00 h

#2 Updated by miyamoto almost 6 years ago

実装

Push型
以下のクラスを実装した。

InPortDirectProvider
インポートプロバイダクラス
InPortProviderクラスを継承してある。
InterfaceTypeは「direct」に設定してある。

InPortDirectConsumer
インポートコンシュマークラス
InPortConsumerクラスを継承してある。

InPortDirectProviderのファクトリを登録するInPortDirectProviderInit関数、InPortDirectConsumerのファクトリを登録するInPortDirectConsumerInit関数をFactoryInit関数で呼び出すことで「direct」という名前のInterfaceTypeを有効にしている。

OutPortBaseクラスに以下の関数を実装した。

getLocalInPort関数:接続したインポートのサーバントを取得する

またInPortのサーバントの設定のためにcreateConnector関数にコードを追加した。

OutPortPushConnectorクラスに以下の関数を実装した。

setInPort関数:ダイレクトで接続する場合にインポートのサーバントを設定する

データの変数への書き込みのためにwrite関数にコードを追加した。
変数宣言のためにコンストラクタにコードを追加した。

InPortクラスに以下の関数を実装した。

write関数:変数_valueにデータを書き込む

変数読み込みのためにread関数にコードを追加した。
データ
変数宣言のためにコンストラクタにコードを追加した。

まずOutPortBaseオブジェクトのcreateConnector関数内でgetLocalInPort関数によりインポートのサーバントを取得し、OutPortPushConnectorオブジェクトのsetInPort関数でインポートのサーバントを設定する。

inport = self.getLocalInPort(profile)
(中略)
connector.setInPort(inport)

そしてOutPortPushConnectorオブジェクトのwrite関数内でインポートオブジェクトのwrite関数を呼び出せばデータを直接書き込める。

self._directInPort.write(data)

バッファがないためデータ書き込んだ際にInPortオブジェクトの変数_directInPortをTrueにして、読み込んだ時にFalseにしている。

isNew関数は_directInPortを返し、isEmpty関数は_directInPortの否定を返す。

Pull型
以下のクラスを実装した。

OutPortDirectProvider
アウトポートプロバイダクラス
OutPortProviderクラスを継承してある。
InterfaceTypeは「direct」に設定してある。

OutPortDirectConsumer
アウトポートコンシュマークラス
OutPortConsumerクラスを継承してある。

Push型と同じく、Init関数を呼び出すことで「direct」のInterfaceTypeが有効になる。

OutPortPullConnectorクラスに以下の関数を追加した。

setInPort関数:ダイレクトに接続する際にInPortオブジェクトにOutPortPullConnectorオブジェクトを設定する
read関数:データをダイレクトに読み込む

変数書き込みのためにwrite関数にコードを追加した。
変数宣言のためにコンストラクタにもコードを追加した。

InPortクラスに以下の関数を追加した。

addOutPortConnector:対象のOutPortPullConnectorオブジェクトをリストに追加する
removeOutPortConnector:対象のOutPortPullConnectorオブジェクトをリストから削除する

データ読み込みのためにread関数にコードを追加した。
変数宣言のためにコンストラクタにもコードを追加した。

まず、Push型と同じくOutPortBaseオブジェクトのcreateConnector関数内でInPortのサーバントをOutPortPullConnectorオブジェクトのsetInPort関数に渡す。
OutPortPullConnectorオブジェクトのsetInPort関数ではInPortオブジェクトのaddOutPortConnector関数を呼び出しリスト_outPortConnectorListにOutPortPullConnectorオブジェクトを追加している。
OutPortPullConnectorオブジェクトのwrite関数で変数にデータを書き込み、InPortオブジェクトのread関数でリストのサイズが1以上の時にリスト内のOutPortPullConnectorオブジェクトから変数を読み込む。
切断された時はOutPortPullConnectorオブジェクトのdisconnect関数内でInPortオブジェクトのremoveOutPortConnector関数を呼び出しリストから削除する。

テスト

添付したテスト用コードでテストを行った。
テスト用コードは以下の動作を行う。

setUp関数

マネージャ初期化
self.manager = OpenRTM_aist.Manager.init(sys.argv)
self.manager.activateManager()

データポート生成
self._d_in = RTC.TimedLong(RTC.Time(0,0),0)
self._inIn = OpenRTM_aist.InPort("in", self._d_in)
prop = OpenRTM_aist.Properties()
self._inIn.init(prop)
self.inport_obj = self._inIn.getPortRef()

→インポートとアウトポートを生成する

test_Push関数

isNew関数でデータが書き込まれたか判定できるかの確認
self._d_out.data = 100
self._outOut.write()
ret = self._inIn.isNew()
self.assertTrue(ret)

read関数でデータがダイレクトに読み込めるかの確認

data = self._inIn.read()
self.assertEqual(data.data, 100)
self.assertTrue(data is self._d_out)

test_Pull関数

データをダイレクトに読み込めるかの確認
data = self._inIn.read()
self.assertEqual(data.data, 100)
self.assertTrue(data is self._d_out)

補足

プロバイダ、コンシュマーのファクトリを登録した際にRTシステムエディタのコネクタの設定でInterfaceTypeが増殖する不具合が発生した。
調べてみたところOutPortBaseクラスとInPortBaseクラスのinitProviders関数とinitProviders関数に問題があったので修正した。

self.appendProperty("dataport.interface_type",
OpenRTM_aist.flatten(consumer_types))


for consumer_type in consumer_types:
self.appendProperty("dataport.interface_type",consumer_type)

self.appendProperty("dataport.interface_type",
OpenRTM_aist.flatten(provider_types))


for provider_type in provider_types:
self.appendProperty("dataport.interface_type",provider_type)

#3 Updated by miyamoto over 5 years ago

  • % Done changed from 80 to 90

Pull型の実装を一部変更した。

OutPortPullConnectorのread関数でコールバックを呼び出すように変更した。

#4 Updated by miyamoto over 5 years ago

  • % Done changed from 90 to 100

#5 Updated by n-ando about 4 years ago

  • Status changed from 新規 to 終了

Also available in: Atom PDF