OutPort.py

説明を見る。
00001 #!/usr/bin/env python
00002 # -*- coding: euc-jp -*-
00003 
00004 
00005 ##
00006 # @file OutPort.py
00007 # @brief OutPort class
00008 # @date $Date: 2007/09/19$
00009 # @author Noriaki Ando <n-ando@aist.go.jp> and Shinji Kurihara
00010 # 
00011 # Copyright (C) 2006-2008
00012 #     Noriaki Ando
00013 #     Task-intelligence Research Group,
00014 #     Intelligent Systems Research Institute,
00015 #     National Institute of
00016 #         Advanced Industrial Science and Technology (AIST), Japan
00017 #     All rights reserved.
00018 
00019 
00020 from omniORB import any
00021 
00022 import OpenRTM
00023 
00024 ##
00025 # @if jp
00026 # @brief 時間単位変換用定数
00027 # @else
00028 # @endif
00029 usec_per_sec = 1000000
00030 
00031 
00032 import time
00033 
00034 
00035 
00036 ##
00037 # @if jp
00038 # @class Time
00039 # @brief 時間管理用クラス
00040 # 
00041 # 指定した時間値を保持するためのクラス。
00042 # 
00043 # @since 0.4.1
00044 # 
00045 # @else
00046 # 
00047 # @endif
00048 class Time:
00049 
00050 
00051 
00052   ##
00053   # @if jp
00054   # @brief コンストラクタ
00055   #
00056   # コンストラクタ。
00057   #
00058   # @param self
00059   #
00060   # @else
00061   # @brief Constructor.
00062   #
00063   # Constructor.
00064   #
00065   # @param self
00066   #
00067   # @endif
00068   def __init__(self):
00069     global usec_per_sec
00070     tm = time.time()
00071     tm_f       = tm - int(tm)     # 小数部の取り出し
00072     self.sec   = int(tm - tm_f)   # 整数部の取り出し
00073     self.usec  = int(tm_f * usec_per_sec) # sec -> usec (micro second)
00074 
00075 
00076 
00077 ##
00078 # @if jp
00079 #
00080 # @class OutPort
00081 #
00082 # @brief OutPort クラス
00083 # 
00084 # OutPort 用クラス
00085 #
00086 # @since 0.2.0
00087 #
00088 # @else
00089 # 
00090 # @endif
00091 class OutPort(OpenRTM.OutPortBase):
00092   """
00093   """
00094 
00095 
00096 
00097   ##
00098   # @if jp
00099   #
00100   # @brief コンストラクタ
00101   #
00102   # コンストラクタ
00103   #
00104   # @param self
00105   # @param name ポート名
00106   # @param value このポートにバインドされるデータ変数
00107   # @param buffer_ バッファ
00108   #
00109   # @else
00110   #
00111   # @brief Constructor
00112   #
00113   # @endif
00114   def __init__(self, name, value, buffer_):
00115     OpenRTM.OutPortBase.__init__(self, name)
00116     self._buffer         = buffer_
00117     self._value          = value
00118     self._timeoutTick    = 1000 # timeout tick: 1ms
00119     self._readBlock      = False
00120     self._readTimeout    = 0
00121     self._writeBlock     = False
00122     self._writeTimeout   = 0
00123     self._OnWrite        = None
00124     self._OnWriteConvert = None
00125     self._OnRead         = None
00126     self._OnReadConvert  = None
00127     self._OnOverflow     = None
00128     self._OnUnderflow    = None
00129 
00130 
00131   ##
00132   # @if jp
00133   # @brief 最新データか確認
00134   #
00135   # 現在のバッファ位置に格納されているデータが最新データか確認する。
00136   #
00137   # @param self
00138   #
00139   # @return 最新データ確認結果
00140   #            ( true:最新データ.データはまだ読み出されていない
00141   #             false:過去のデータ.データは既に読み出されている)
00142   #
00143   # @else
00144   #
00145   # @endif
00146   def isNew(self):
00147     return self._buffer.isNew()
00148 
00149 
00150   ##
00151   # @if jp
00152   #
00153   # @brief データ書き込み
00154   #
00155   # ポートへデータを書き込む。
00156   #
00157   # - コールバックファンクタ OnWrite がセットされている場合、
00158   #   OutPort が保持するバッファに書き込む前に OnWrite が呼ばれる。
00159   # - OutPort が保持するバッファがオーバーフローを検出できるバッファであり、
00160   #   かつ、書き込む際にバッファがオーバーフローを検出した場合、
00161   #   コールバックファンクタ OnOverflow が呼ばれる。
00162   # - コールバックファンクタ OnWriteConvert がセットされている場合、
00163   #   バッファ書き込み時に、 OnWriteConvert の operator() の戻り値が
00164   #   バッファに書き込まれる。
00165   #
00166   # @param self
00167   # @param value 書き込み対象データ
00168   #
00169   # @return 書き込み処理結果(書き込み成功:true、書き込み失敗:false)
00170   #
00171   # @else
00172   #
00173   # @brief Write data
00174   #
00175   # @endif
00176   # virtual bool write(const DataType& value)
00177   ##
00178   # @if jp
00179   #
00180   # @brief データ書き込み
00181   #
00182   # ポートへデータを書き込む。
00183   # 設定された値をポートに書き込む。
00184   #
00185   # @param self
00186   # @param value 書き込み対象データ
00187   #
00188   # @return 書き込み処理結果(書き込み成功:true、書き込み失敗:false)
00189   #
00190   # @else
00191   #
00192   # @endif
00193   # bool operator<<(DataType& value)
00194   def write(self, value=None):
00195     if not value:
00196       value=self._value
00197 
00198     global usec_per_sec
00199     
00200     if self._OnWrite:
00201       self._OnWrite(value)
00202 
00203     timeout = self._writeTimeout
00204 
00205     tm_pre = Time()
00206 
00207     # blocking and timeout wait
00208     count = 0
00209     while self._writeBlock and self._buffer.isFull():
00210       if self._writeTimeout < 0:
00211         time.sleep(self._timeoutTick/usec_per_sec)
00212         continue
00213       
00214         
00215       # timeout wait
00216       tm_cur = Time()
00217 
00218       sec  = tm_cur.sec - tm_pre.sec
00219       usec = tm_cur.usec - tm_pre.usec
00220 
00221       timeout -= (sec * usec_per_sec + usec)
00222 
00223       if timeout < 0:
00224         break
00225       tm_pre = tm_cur
00226       time.sleep(self._timeoutTick/usec_per_sec)
00227       count += 1
00228       
00229     if self._buffer.isFull():
00230       if self._OnOverflow:
00231         self._OnOverflow(value)
00232       return False
00233       
00234     if not self._OnWriteConvert:
00235       self._buffer.put(value)
00236     else:
00237       self._buffer.put(self._OnWriteConvert(value))
00238 
00239     self.notify()
00240     return True
00241 
00242 
00243   ##
00244   # @if jp
00245   #
00246   # @brief データ読み出し
00247   #
00248   # DataPort から値を読み出す
00249   #
00250   # - コールバックファンクタ OnRead がセットされている場合、
00251   #   DataPort が保持するバッファから読み出す前に OnRead が呼ばれる。
00252   # - DataPort が保持するバッファがアンダーフローを検出できるバッファで、
00253   #   かつ、読み出す際にバッファがアンダーフローを検出した場合、
00254   #   コールバックファンクタ OnUnderflow が呼ばれる。
00255   # - コールバックファンクタ OnReadConvert がセットされている場合、
00256   #   バッファ書き込み時に、 OnReadConvert の operator() の戻り値が
00257   #   read()の戻り値となる。
00258   # - setReadTimeout() により読み出し時のタイムアウトが設定されている場合、
00259   #   バッファアンダーフロー状態が解除されるまでタイムアウト時間だけ待ち、
00260   #   OnUnderflow がセットされていればこれを呼び出して戻る
00261   #
00262   # @param self
00263   # @param value 読み出したデータ
00264   #
00265   # @return 読み出し処理実行結果(読み出し成功:true、読み出し失敗:false)
00266   #
00267   # @else
00268   #
00269   # @brief Read data
00270   #
00271   # @endif
00272   def read(self, value):
00273     if self._OnRead:
00274       self._OnRead()
00275 
00276     timeout = self._readTimeout
00277     tm_pre = Time()
00278 
00279     # blocking and timeout wait
00280     while self._readBlock and self._buffer.isEmpty():
00281       if self._readTimeout < 0:
00282         time.sleep(self._timeoutTick/usec_per_sec)
00283         continue
00284 
00285       # timeout wait
00286       tm_cur = Time()
00287       sec  = tm_cur.sec - tm_pre.sec
00288       usec = tm_cur.usec - tm_pre.usec
00289       
00290       timeout -= (sec * usec_per_sec + usec)
00291       if timeout < 0:
00292         break
00293       tm_pre = tm_cur
00294       time.sleep(self._timeoutTick/usec_per_sec)
00295 
00296     if self._buffer.isEmpty():
00297       if self._OnUnderflow:
00298         value[0] = self._OnUnderflow()
00299         return False
00300       else:
00301         return False
00302 
00303     if not self._OnReadConvert:
00304       value[0] = self._buffer.get()
00305       return True
00306     else:
00307       value[0] = self._OnReadConvert(self._buffer.get())
00308       return true
00309 
00310     # never comes here
00311     return False
00312 
00313 
00314   ##
00315   # @if jp
00316   #
00317   # @brief データ読み出し処理のブロックモードの設定
00318   #
00319   # 読み出し処理に対してブロックモードを設定する。
00320   # ブロックモードを指定した場合、読み出せるデータを受信するかタイムアウト
00321   # が発生するまで、 read() メソッドの呼びだしがブロックされる。
00322   #
00323   # @param self
00324   # @param block ブロックモードフラグ
00325   #
00326   # @else
00327   #
00328   # @brief Set read() block mode
00329   #
00330   # @endif
00331   def setReadBlock(self, block):
00332     self._readBlock = block
00333 
00334 
00335   ##
00336   # @if jp
00337   #
00338   # @brief データ書き込み処理のブロックモードの設定
00339   #
00340   # 書き込み処理に対してブロックモードを設定する。
00341   # ブロックモードを指定した場合、バッファに書き込む領域ができるか
00342   # タイムアウトが発生するまで write() メソッドの呼びだしがブロックされる。
00343   #
00344   # @param self
00345   # @param block ブロックモードフラグ
00346   #
00347   # @else
00348   #
00349   # @brief Set read() block mode
00350   #
00351   # @endif
00352   def setWriteBlock(self, block):
00353     self._writeBlock = block
00354 
00355 
00356   ##
00357   # @if jp
00358   #
00359   # @brief 読み出し処理のタイムアウト時間の設定
00360   # 
00361   # read() のタイムアウト時間を usec で設定する。
00362   # read() はブロックモードでなければならない。
00363   #
00364   # @param self
00365   # @param timeout タイムアウト時間 [usec]
00366   #
00367   # @else
00368   #
00369   # @brief Set read() timeout
00370   #
00371   # @endif
00372   def setReadTimeout(self, timeout):
00373     self._readTimeout = timeout
00374 
00375 
00376   ##
00377   # @if jp
00378   #
00379   # @brief 書き込み処理のタイムアウト時間の設定
00380   # 
00381   # write() のタイムアウト時間を usec で設定する。
00382   # write() はブロックモードでなければならない。
00383   #
00384   # @param self
00385   # @param timeout タイムアウト時間 [usec]
00386   #
00387   # @else
00388   #
00389   # @brief Set write() timeout
00390   #
00391   # @endif
00392   def setWriteTimeout(self, timeout):
00393     self._writeTimeout = timeout
00394 
00395 
00396   ##
00397   # @if jp
00398   #
00399   # @brief OnWrite コールバックの設定
00400   #
00401   # データ書き込み直前に呼ばれる OnWrite コールバックファンクタを設定する。
00402   #
00403   # @param self
00404   # @param on_write OnWrite コールバックファンクタ
00405   #
00406   # @else
00407   #
00408   # @brief Set OnWrite callback
00409   #
00410   # @endif
00411   def setOnWrite(self, on_write):
00412     self._OnWrite = on_write
00413 
00414 
00415   ##
00416   # @if jp
00417   #
00418   # @brief OnWriteConvert コールバックの設定
00419   #
00420   # データ書き込み時に呼ばれる OnWriteConvert コールバックファンクタを設定
00421   # する。
00422   # このコールバック関数の処理結果が書き込まれる。
00423   # このため書き込みデータのフィルタリングが可能となる。
00424   #
00425   # @param self
00426   # @param on_wconvert OnWriteConvert コールバックファンクタ
00427   #
00428   # @else
00429   #
00430   # @brief Set OnWriteConvert callback
00431   #
00432   # @endif
00433   def setOnWriteConvert(self, on_wconvert):
00434     self._OnWriteConvert = on_wconvert
00435 
00436 
00437   ##
00438   # @if jp
00439   #
00440   # @brief OnOverflow コールバックの設定
00441   #
00442   # バッファフルによりデータ書き込みができない場合に呼び出される OnOverflow
00443   # コールバックファンクタを設定する。
00444   #
00445   # @param self
00446   # @param on_overflow OnOverflow コールバックファンクタ
00447   #
00448   # @else
00449   #
00450   # @brief Set OnOverflow callback
00451   #
00452   # @endif
00453   def setOnOverflow(self, on_overflow):
00454     self._OnOverflow = on_overflow
00455 
00456 
00457   ##
00458   # @if jp
00459   #
00460   # @brief OnRead コールバックの設定
00461   #
00462   # データ読み出し直前に呼び出される OnRead コールバックファンクタを設定
00463   # する。
00464   #
00465   # @param self
00466   # @param on_read OnRead コールバックファンクタ
00467   #
00468   # @else
00469   #
00470   # @brief Set OnRead callback
00471   #
00472   # @endif
00473   def setOnRead(self, on_read):
00474     self._OnRead = on_read
00475 
00476 
00477   ##
00478   # @if jp
00479   #
00480   # @brief OnReadConvert コールバックの設定
00481   #
00482   # データ読み出し時に呼ばれる OnReadConvert コールバックファンクタを設定
00483   # する。
00484   # このコールバック関数の処理結果が読み込まれる。
00485   # このため読み込みデータのフィルタリングが可能となる。
00486   #
00487   # @param self
00488   # @param on_rconvert OnReadConvert コールバックファンクタ
00489   #
00490   # @else
00491   #
00492   # @brief Set OnReadConvert callback
00493   #
00494   # @endif
00495   def setOnReadConvert(self, on_rconvert):
00496     self._OnReadConvert = on_rconvert
00497 
00498 
00499   ##
00500   # @if jp
00501   #
00502   # @brief OnUnderflow コールバックの設定
00503   #
00504   # バッファエンプティにより読み出せるデータがない場合に呼び出される
00505   # コールバックファンクタ OnUnderflow を設定する。
00506   #
00507   # @param self
00508   # @param on_underflow OnUnderflow コールバックファンクタ
00509   #
00510   # @else
00511   #
00512   # @brief Set OnUnderflow callback
00513   #
00514   # @endif
00515   def setOnUnderflow(self, on_underflow):
00516     self._OnUnderflow = on_underflow
00517 
00518 
00519   ##
00520   # @if jp
00521   #
00522   # @brief データ型名取得用メソッド
00523   #
00524   # データの型名を取得するため、InPortCorbaProviderから呼ばれる。
00525   # 
00526   # @param self
00527   #
00528   # @return バッファに設定されているデータの型名
00529   #
00530   # @else
00531   #
00532   # @endif
00533   def getPortDataType(self):
00534     val = any.to_any(self._value)
00535     return str(val.typecode().name())

OpenRTMに対してMon Mar 17 15:11:05 2008に生成されました。  doxygen 1.5.4