PeriodicTask.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # -*- coding: euc-jp -*-
00003 
00004 
00005 ##
00006 # @file PeriodicTask.py
00007 # @brief Periodic task template class
00008 # @date $Date$
00009 # @author Noriaki Ando <n-ando@aist.go.jp> and Shinji Kurihara
00010 #
00011 # Copyright (C) 2009
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 import threading
00021 import time
00022 import OpenRTM_aist
00023 
00024 ##
00025 # @if jp
00026 # @class 周期タスクスレッド実行クラス
00027 #
00028 # 特定の関数を周期実行するためのスレッドオブジェクトを実現する。
00029 # 使用手順は以下の通り。
00030 #
00031 # task; // インスタンス生成
00032 # task.setTask(TaskFuncBase(obj, mem_func)); // 実行する関数を与える
00033 # task.activate(); // スレッドをスタートさせる
00034 #
00035 # task.suspend(); // 周期実行を止める
00036 # task.signal(); // 1周期だけ実行
00037 # task.resume(); // 周期実行を再開
00038 #
00039 # task.finalize(); // タスクを終了させる
00040 # 
00041 # @else
00042 # @brief
00043 #
00044 # @endif
00045 #
00046 class PeriodicTask(OpenRTM_aist.Task):
00047   """
00048   """
00049 
00050   ##
00051   # @if jp
00052   # @brief ctor
00053   # @else
00054   # @brief ctor
00055   # @endif
00056   #
00057   def __init__(self):
00058     OpenRTM_aist.Task.__init__(self)
00059     self._period         = OpenRTM_aist.TimeValue(0.0)
00060     self._nowait         = False
00061     self._func           = 0
00062     self._deleteInDtor   = True
00063     self._alive          = self.alive_t(False)
00064     self._suspend        = self.suspend_t(False)
00065 
00066     # variables for execution time measurement
00067     self._execMeasure    = False
00068     self._execCount      = 0
00069     self._execCountMax   = 10
00070     self._execStat       = self.statistics_t()
00071     self._execTime       = OpenRTM_aist.TimeMeasure()
00072 
00073     # variables for period time measurement
00074     self._periodMeasure  = False
00075     self._periodCount    = 0
00076     self._periodCountMax = 10
00077     self._periodStat     = self.statistics_t()
00078     self._periodTime     = OpenRTM_aist.TimeMeasure()
00079 
00080     return
00081 
00082     
00083   ##
00084   # @if jp
00085   # @brief dtor
00086   # @else
00087   # @brief dtor
00088   # @endif
00089   #
00090   def __del__(self, Task=OpenRTM_aist.Task):
00091     self.finalize()
00092     self.wait()
00093     Task.__del__(self)
00094     return
00095   
00096     
00097   ##
00098   # @if jp
00099   # @brief タスク実行を開始する
00100   #
00101   # タスクの実行を開始するためにスレッドをスタートさせる。  タスクが
00102   # 正常に開始された場合は true が返り、すでにタスクが開始済み、また
00103   # は実行するタスクが設定されていなければ false を返す。
00104   #
00105   # @return true: 正常開始、false: スレッド済みかタスクが未設定である。
00106   #
00107   # @else
00108   # @brief Starting the task
00109   #
00110   # Starting a thread to execute a task.  If the task/thread is
00111   # started properly, it will return 'TRUE'.  if the task/thread
00112   # are already started or task function object is not set, 'FALSE'
00113   # will be returned.
00114   #
00115   # @return true: normal start, false: already started  or task is not set
00116   #
00117   # @endif
00118   #
00119   # virtual void activate();
00120   def activate(self):
00121     guard = OpenRTM_aist.ScopedLock(self._alive.mutex)
00122     if not self._func:
00123       return
00124 
00125     if self._alive.value:
00126       return
00127 
00128     self._alive.value = True
00129     OpenRTM_aist.Task.activate(self)
00130     return
00131 
00132 
00133   ##
00134   # @if jp
00135   # @brief タスク実行を終了する
00136   #
00137   # 実行中のタスクを終了する。
00138   #
00139   # @else
00140   # @brief Finalizing the task
00141   #
00142   # Finalizing the task running.
00143   #
00144   # @endif
00145   #
00146   # virtual void finalize();
00147   def finalize(self):
00148     guard = OpenRTM_aist.ScopedLock(self._alive.mutex)
00149     self._alive.value = False
00150 
00151     self._suspend.cond.acquire()
00152     self._suspend.suspend = False
00153     self._suspend.cond.notify()
00154     self._suspend.cond.release()
00155     return
00156 
00157 
00158   ##
00159   # @if jp
00160   # @brief タスク実行を中断する
00161   #
00162   # 実行中のタスクを中断する。
00163   #
00164   # @else
00165   # @brief Suspending the task
00166   #
00167   # Suspending the task running.
00168   #
00169   # @endif
00170   #
00171   # virtual int suspend(void);
00172   def suspend(self):
00173     self._suspend.cond.acquire()
00174     self._suspend.suspend = True
00175     self._suspend.cond.release()
00176     return 0
00177     
00178 
00179   ##
00180   # @if jp
00181   # @brief 中断されているタスクを再開する
00182   #
00183   # 中断されているタスクを再開する
00184   #
00185   # @else
00186   # @brief Resuming the suspended task
00187   #
00188   # Resuming the suspended task
00189   #
00190   # @endif
00191   #
00192   # virtual int resume(void);
00193   def resume(self):
00194     self._periodTime.reset()
00195     self._execTime.reset()
00196     self._suspend.cond.acquire()
00197     self._suspend.suspend = False
00198     self._suspend.cond.notify()
00199     self._suspend.cond.release()
00200     return 0
00201 
00202 
00203   ##
00204   # @if jp
00205   # @brief 中断されているタスクを1周期だけ実行する
00206   #
00207   # 中断されているタスクを1周期だけ実行する
00208   #
00209   # @else
00210   # @brief Executing the suspended task one tick
00211   #
00212   # Executing the suspended task one tick
00213   #
00214   # @endif
00215   #
00216   # virtual void signal();
00217   def signal(self):
00218     self._suspend.cond.acquire()
00219     self._suspend.cond.notify()
00220     self._suspend.cond.release()
00221     return
00222 
00223 
00224   ##
00225   # @if jp
00226   # @brief タスク実行関数をセットする
00227   #
00228   # @param func int (*)() 型の関数ポインタ
00229   #
00230   # @else
00231   # @brief Setting task execution function
00232   #
00233   # @param func Set int (*)() type function pointer
00234   #
00235   # @endif
00236   #
00237   # virtual bool setTask(TaskFuncBase* func, bool delete_in_dtor = true);
00238   def setTask(self, func, delete_in_dtor = True):
00239     if not func:
00240       return False
00241 
00242     self._deleteInDtor = delete_in_dtor
00243     self._func = func
00244     return True
00245 
00246   
00247   ##
00248   # @if jp
00249   # @brief タスク実行周期をセットする
00250   #
00251   # @param period 実行周期 [sec]
00252   #
00253   # @else
00254   # @brief Setting task execution period
00255   #
00256   # @param period Execution period [sec]
00257   #
00258   # @endif
00259   #
00260   # virtual void setPeriod(double period);
00261   # virtual void setPeriod(TimeValue& period);
00262   def setPeriod(self, period):
00263     if type(period) == float:
00264       self._period = OpenRTM_aist.TimeValue(period)
00265     else:
00266       self._period = period
00267     
00268     if self._period.sec() == 0 and self._period.usec() == 0:
00269       self._nowait = True
00270       return
00271 
00272     self._nowait = False
00273     return
00274 
00275 
00276   ##
00277   # @if jp
00278   # @brief タスク関数実行時間計測を有効にするか
00279   # @else
00280   # @brief 
00281   # @endif
00282   #
00283   # virtual void executionMeasure(bool value);
00284   def executionMeasure(self, value):
00285     self._execMeasure = value
00286     return
00287 
00288     
00289   ##
00290   # @if jp
00291   # @brief タスク関数実行時間計測周期
00292   # @else
00293   # @brief 
00294   # @endif
00295   #
00296   # virtual void executionMeasureCount(int n);
00297   def executionMeasureCount(self, n):
00298     self._execCountMax = n
00299     return
00300     
00301 
00302   ##
00303   # @if jp
00304   # @brief タスク周期時間計測を有効にするか
00305   # @else
00306   # @brief 
00307   # @endif
00308   #
00309   # virtual void periodicMeasure(bool value);
00310   def periodicMeasure(self, value):
00311     self._periodMeasure = value
00312     return
00313 
00314   ##
00315   # @if jp
00316   # @brief タスク周期時間計測周期
00317   # @else
00318   # @brief 
00319   # @endif
00320   #
00321   # virtual void periodicMeasureCount(int n);
00322   def periodicMeasureCount(self, n):
00323     self._periodCountMax = n
00324     return
00325 
00326 
00327   ##
00328   # @if jp
00329   # @brief タスク関数実行時間計測結果を取得
00330   # @else
00331   # @brief 
00332   # @endif
00333   #
00334   # virtual TimeMeasure::Statistics getExecStat();
00335   def getExecStat(self):
00336     guard = OpenRTM_aist.ScopedLock(self._execStat.mutex)
00337     return self._execStat.stat
00338     
00339     
00340   ##
00341   # @if jp
00342   # @brief タスク周期時間計測結果を取得
00343   # @else
00344   # @brief 
00345   # @endif
00346   #
00347   # virtual TimeMeasure::Statistics getPeriodStat();
00348   def getPeriodStat(self):
00349     guard = OpenRTM_aist.ScopedLock(self._periodStat.mutex)
00350     return self._periodStat.stat
00351     
00352 
00353   ## virtual int svc();
00354   def svc(self):
00355 
00356     while self._alive.value: # needs lock?
00357       if self._periodMeasure:
00358         self._periodTime.tack()
00359         
00360       # wait if suspended
00361       self._suspend.cond.acquire()
00362       if self._suspend.suspend:
00363         self._suspend.cond.wait()
00364         # break if finalized
00365         if not self._alive.value:
00366           self._suspend.cond.release()
00367           return 0
00368       self._suspend.cond.release()
00369           
00370       if self._periodMeasure:
00371         self._periodTime.tick()
00372 
00373       # task execution
00374       if self._execMeasure:
00375         self._execTime.tick()
00376 
00377       self._func()
00378       if self._execMeasure:
00379         self._execTime.tack()
00380 
00381       # wait for next period
00382       self.updateExecStat()
00383       self.sleep()
00384       self.updatePeriodStat()
00385 
00386 
00387     return 0
00388         
00389         
00390   ## virtual void sleep();
00391   def sleep(self):
00392     if self._nowait:
00393       return
00394 
00395     sleep_sec = self._period - self._execTime.interval()
00396 
00397     if sleep_sec.toDouble() < 0:
00398       return
00399 
00400     time.sleep(sleep_sec.toDouble())
00401     return
00402 
00403 
00404   ## virtual void updateExecStat();
00405   def updateExecStat(self):
00406     if self._execCount > self._execCountMax:
00407       guard = OpenRTM_aist.ScopedLock(self._execStat.mutex)
00408       self._execStat.stat = self._execTime.getStatistics()
00409       self._execCount = 0
00410 
00411     self._execCount += 1
00412     return
00413 
00414 
00415   ## virtual void updatePeriodStat();
00416   def updatePeriodStat(self):
00417     if self._periodCount > self._periodCountMax:
00418       guard = OpenRTM_aist.ScopedLock(self._periodStat.mutex)
00419       self._periodStat.stat = self._periodTime.getStatistics()
00420       self_periodCount = 0
00421 
00422     self._periodCount += 1
00423     return
00424 
00425 
00426   # alive flag
00427   class alive_t:
00428     def __init__(self, val):
00429       self.value = val
00430       self.mutex = threading.RLock()
00431       return
00432 
00433   # suspend flag
00434   class suspend_t:
00435     def __init__(self, sus):
00436       self.suspend = sus
00437       self.mutex = threading.RLock()
00438       self.cond = threading.Condition(self.mutex)
00439       return
00440 
00441       
00442   # time measurement statistics struct
00443   class statistics_t:
00444     def __init__(self):
00445       self.stat = OpenRTM_aist.TimeMeasure.Statistics()
00446       self.mutex = threading.RLock()
00447 
00448 


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