InPort.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # -*- coding: euc-jp -*-
00003 
00004 ##
00005 # @file InPort.py
00006 # @brief InPort template class
00007 # @date $Date: 2007/09/20 $
00008 # @author Noriaki Ando <n-ando@aist.go.jp> and Shinji Kurihara
00009 # 
00010 # Copyright (C) 2003-2008
00011 #     Task-intelligence Research Group,
00012 #     Intelligent Systems Research Institute,
00013 #     National Institute of
00014 #         Advanced Industrial Science and Technology (AIST), Japan
00015 #     All rights reserved.
00016 
00017 from omniORB import *
00018 from omniORB import any
00019 import sys
00020 import copy
00021 import time
00022 
00023 import OpenRTM_aist
00024 
00025 ##
00026 # @if jp
00027 #
00028 # @class InPort
00029 #
00030 # @brief InPort クラス
00031 # 
00032 # InPort の実装クラス。
00033 # InPort は内部にリングバッファを持ち、外部から送信されたデータを順次
00034 # このリングバッファに格納する。リングバッファのサイズはデフォルトで64と
00035 # なっているが、コンストラクタ引数によりサイズを指定することができる。
00036 # データはフラグによって未読、既読状態が管理され、isNew(), getNewDataLen()
00037 # getNewList(), getNewListReverse() 等のメソッドによりハンドリングすることが
00038 # できる。
00039 #
00040 # @since 0.2.0
00041 #
00042 # @else
00043 #
00044 # @class InPort
00045 #
00046 # @brief InPort template class
00047 #
00048 # This class template provides interfaces to input port.
00049 # Component developer can define input value, which act as input
00050 # port from other components, using this template.
00051 # This is class template. This class have to be incarnated class as port
00052 # value types. This value types are previously define RtComponent IDL.
00053 # ex. type T: TimedFload, TimedLong etc... 
00054 #
00055 # @since 0.2.0
00056 #
00057 # @endif
00058 class InPort(OpenRTM_aist.InPortBase):
00059   """
00060   """
00061 
00062 
00063 
00064   ##
00065   # @if jp
00066   #
00067   # @brief コンストラクタ
00068   #
00069   # コンストラクタ。
00070   #
00071   # @param self
00072   # @param name InPort 名。InPortBase:name() により参照される。
00073   # @param value この InPort にバインドされる変数
00074   # @param read_block 読込ブロックフラグ。
00075   #        データ読込時に未読データがない場合、次のデータ受信までブロックする
00076   #        かどうかを設定(デフォルト値:False)
00077   # @param write_block 書込ブロックフラグ。
00078   #        データ書込時にバッファがフルであった場合、バッファに空きができる
00079   #        までブロックするかどうかを設定(デフォルト値:False)
00080   # @param read_timeout 読込ブロックを指定していない場合の、データ読取タイム
00081   #        アウト時間(ミリ秒)(デフォルト値:0)
00082   # @param write_timeout 書込ブロックを指定していない場合の、データ書込タイム
00083   #        アウト時間(ミリ秒)(デフォルト値:0)
00084   #
00085   # @else
00086   #
00087   # @brief A constructor.
00088   #
00089   # Setting channel name and registering channel value.
00090   #
00091   # @param self
00092   # @param name A name of the InPort. This name is referred by
00093   #             InPortBase::name().
00094   # @param value A channel value related with the channel.
00095   # @param read_block
00096   # @param write_block
00097   # @param read_timeout
00098   # @param write_timeout
00099   #
00100   # @endif
00101   def __init__(self, name, value, buffer=None,
00102                read_block=False, write_block=False,
00103                read_timeout=0, write_timeout = 0):
00104     OpenRTM_aist.InPortBase.__init__(self, name, OpenRTM_aist.toTypename(value))
00105     self._name           = name
00106     self._value          = value
00107     self._OnRead         = None
00108     self._OnReadConvert  = None
00109 
00110 
00111   def __del__(self, InPortBase=OpenRTM_aist.InPortBase):
00112     InPortBase.__del__(self)
00113     return
00114 
00115   ##
00116   # @if jp
00117   # @brief ポート名称を取得する。
00118   #
00119   # ポート名称を取得する。
00120   #
00121   # @param self
00122   #
00123   # @return ポート名称
00124   #
00125   # @else
00126   #
00127   # @endif
00128   #
00129   # const char* name()
00130   def name(self):
00131     return self._name
00132 
00133 
00134   ##
00135   # @if jp
00136   # @brief 最新データか確認
00137   #
00138   # 現在のバッファ位置に格納されているデータが最新データか確認する。
00139   #
00140   # @param self
00141   #
00142   # @return 最新データ確認結果
00143   #            ( true:最新データ.データはまだ読み出されていない
00144   #             false:過去のデータ.データは既に読み出されている)
00145   #
00146   # @else
00147   #
00148   # @endif
00149   #
00150   # bool isNew()
00151   def isNew(self):
00152     self._rtcout.RTC_TRACE("isNew()")
00153 
00154     if len(self._connectors) == 0:
00155       self._rtcout.RTC_DEBUG("no connectors")
00156       return False
00157 
00158     r = self._connectors[0].getBuffer().readable()
00159     if r > 0:
00160       self._rtcout.RTC_DEBUG("isNew() = True, readable data: %d",r)
00161       return True
00162 
00163     self._rtcout.RTC_DEBUG("isNew() = False, no readable data")
00164     return False
00165 
00166 
00167   ##
00168   # @if jp
00169   #
00170   # @brief バッファが空かどうか確認する
00171   # 
00172   # InPortのバッファが空かどうかを bool 値で返す。
00173   # 空の場合は true, 未読データがある場合は false を返す。
00174   #
00175   # @return true  バッファは空
00176   #         false バッファに未読データがある
00177   # 
00178   # @else
00179   #
00180   # @brief Check whether the data is newest
00181   # 
00182   # Check whether the data stored at a current buffer position is newest.
00183   #
00184   # @return Newest data check result
00185   #         ( true:Newest data. Data has not been readout yet.
00186   #          false:Past data.Data has already been readout.)
00187   # 
00188   # @endif
00189   #
00190   # bool isEmpty()
00191   def isEmpty(self):
00192     self._rtcout.RTC_TRACE("isEmpty()")
00193 
00194     if len(self._connectors) == 0:
00195       self._rtcout.RTC_DEBUG("no connectors")
00196       return True
00197 
00198     r = self._connectors[0].getBuffer().readable()
00199     if r == 0:
00200       self._rtcout.RTC_DEBUG("isEmpty() = true, buffer is empty")
00201       return True
00202       
00203     self._rtcout.RTC_DEBUG("isEmpty() = false, data exists in the buffer")
00204     return False
00205 
00206 
00207   ##
00208   # @if jp
00209   #
00210   # @brief DataPort から値を読み出す
00211   #
00212   # InPortに書き込まれたデータを読みだす。接続数が0、またはバッファに
00213   # データが書き込まれていない状態で読みだした場合の戻り値は不定である。
00214   # バッファが空の状態のとき、
00215   # 事前に設定されたモード (readback, do_nothing, block) に応じて、
00216   # 以下のような動作をする。
00217   #
00218   # - readback: 最後の値を読みなおす。
00219   #
00220   # - do_nothing: 何もしない
00221   #
00222   # - block: ブロックする。タイムアウトが設定されている場合は、
00223   #       タイムアウトするまで待つ。
00224   #
00225   # バッファが空の状態では、InPortにバインドされた変数の値が返される。
00226   # したがって、初回読み出し時には不定値を返す可能性がある。
00227   # この関数を利用する際には、
00228   #
00229   # - isNew(), isEmpty() と併用し、事前にバッファ状態をチェックする。
00230   # 
00231   # - 初回読み出し時に不定値を返さないようにバインド変数を事前に初期化する
00232   # 
00233   #
00234   # 各コールバック関数は以下のように呼び出される。
00235   # - OnRead: read() 関数が呼ばれる際に必ず呼ばれる。
00236   # 
00237   # - OnReadConvert: データの読み出しが成功した場合、読みだしたデータを
00238   #       引数としてOnReadConvertが呼び出され、戻り値をread()が戻り値
00239   #       として返す。
00240   #
00241   # - OnEmpty: バッファが空のためデータの読み出しに失敗した場合呼び出される。
00242   #        OnEmpty の戻り値を read() の戻り値として返す。
00243   #
00244   # - OnBufferTimeout: データフロー型がPush型の場合に、読み出し
00245   #        タイムアウトのためにデータの読み出しに失敗した場合に呼ばれる。
00246   #
00247   # - OnRecvTimeout: データフロー型がPull型の場合に、読み出しタイムアウト
00248   #        のためにデータ読み出しに失敗した場合に呼ばれる。
00249   #
00250   # - OnReadError: 上記以外の理由で読みだしに失敗した場合に呼ばれる。
00251   #        理由としては、バッファ設定の不整合、例外の発生などが考えられる
00252   #        が通常は起こりえないためバグの可能性がある。
00253   #
00254   # @return 読み出したデータ
00255   #
00256   # @else
00257   #
00258   # @brief Readout the value from DataPort
00259   #
00260   # Readout the value from DataPort
00261   #
00262   # - When Callback functor OnRead is already set, OnRead will be invoked
00263   #   before reading from the buffer held by DataPort.
00264   # - When the buffer held by DataPort can detect the underflow,
00265   #   and when it detected the underflow at reading, callback functor
00266   #   OnUnderflow will be invoked.
00267   # - When callback functor OnReadConvert is already set, the return value of
00268   #   operator() of OnReadConvert will be the return value of read().
00269   # - When timeout of reading is already set by setReadTimeout(),
00270   #   it waits for only timeout time until the state of the buffer underflow
00271   #   is reset, and if OnUnderflow is already set, this will be invoked to 
00272   #   return.
00273   #
00274   # @return Readout data
00275   #
00276   # @endif
00277   #
00278   #  DataType read()
00279   def read(self):
00280     self._rtcout.RTC_TRACE("DataType read()")
00281 
00282     if self._OnRead is not None:
00283       self._OnRead()
00284       self._rtcout.RTC_TRACE("OnRead called")
00285 
00286     if len(self._connectors) == 0:
00287       self._rtcout.RTC_DEBUG("no connectors")
00288       return self._value
00289 
00290     _val = copy.deepcopy(self._value)
00291     cdr = [_val]
00292     ret = self._connectors[0].read(cdr)
00293 
00294 
00295     if ret == OpenRTM_aist.DataPortStatus.PORT_OK:
00296       self._rtcout.RTC_DEBUG("data read succeeded")
00297       self._value = cdr[0]
00298 
00299       if self._OnReadConvert is not None:
00300         self._value = self._OnReadConvert(self._value)
00301         self._rtcout.RTC_DEBUG("OnReadConvert called")
00302         return self._value
00303       return self._value
00304 
00305     elif ret == OpenRTM_aist.DataPortStatus.BUFFER_EMPTY:
00306       self._rtcout.RTC_WARN("buffer empty")
00307       return self._value
00308 
00309     elif ret == OpenRTM_aist.DataPortStatus.BUFFER_TIMEOUT:
00310       self._rtcout.RTC_WARN("buffer read timeout")
00311       return self._value
00312 
00313     self._rtcout.RTC_ERROR("unknown retern value from buffer.read()")
00314     return self._value
00315 
00316 
00317   ##
00318   # @if jp
00319   #
00320   # @brief バインドされた変数に InPort バッファの最新値を読み込む
00321   #
00322   # バインドされたデータに InPort の最新値を読み込む。
00323   # コンストラクタで変数と InPort がバインドされていなければならない。
00324   # このメソッドはポリモーフィックに使用される事を前提としているため、
00325   # 型に依存しない引数、戻り値となっている。
00326   #
00327   # @param self
00328   #
00329   # @else
00330   #
00331   # @brief Read into bound T-type data from current InPort
00332   #
00333   # @endif
00334   def update(self):
00335     self.read()
00336 
00337 
00338   ##
00339   # @if jp
00340   #
00341   # @brief InPort バッファへデータ読み込み時のコールバックの設定
00342   #
00343   # InPort が持つバッファからデータが読み込まれる直前に呼ばれるコールバック
00344   # オブジェクトを設定する。
00345   # 
00346   # @param self
00347   # @param on_read 設定対象コールバックオブジェクト
00348   #
00349   # @else
00350   #
00351   # @endif
00352   def setOnRead(self, on_read):
00353     self._OnRead = on_read
00354 
00355 
00356   ##
00357   # @if jp
00358   #
00359   # @brief InPort バッファへデータ読み出し時のコールバックの設定
00360   #
00361   # InPort が持つバッファからデータが読み出される際に呼ばれるコールバック
00362   # オブジェクトを設定する。コールバックオブジェクトの戻り値がread()メソッド
00363   # の呼出結果となる。
00364   # 
00365   # @param self
00366   # @param on_rconvert 設定対象コールバックオブジェクト
00367   #
00368   # @else
00369   #
00370   # @endif
00371   def setOnReadConvert(self, on_rconvert):
00372     self._OnReadConvert = on_rconvert


openrtm_aist_python
Author(s): Shinji Kurihara
autogenerated on Thu Aug 27 2015 14:17:28