[openrtm-commit:00764] r525 - in branches/work/OpenRTM-aist-Python/OpenRTM_aist: . test
openrtm @ openrtm.org
openrtm @ openrtm.org
2012年 3月 13日 (火) 14:30:46 JST
Author: kurihara
Date: 2012-03-13 14:30:45 +0900 (Tue, 13 Mar 2012)
New Revision: 525
Added:
branches/work/OpenRTM-aist-Python/OpenRTM_aist/ExecutionContextWorker.py
branches/work/OpenRTM-aist-Python/OpenRTM_aist/test/test_ExecutionContextWorker.py
Log:
[incompat,impl,func] ExecutionContextWorker class was implemented. refs #2348
Added: branches/work/OpenRTM-aist-Python/OpenRTM_aist/ExecutionContextWorker.py
===================================================================
--- branches/work/OpenRTM-aist-Python/OpenRTM_aist/ExecutionContextWorker.py (rev 0)
+++ branches/work/OpenRTM-aist-Python/OpenRTM_aist/ExecutionContextWorker.py 2012-03-13 05:30:45 UTC (rev 525)
@@ -0,0 +1,745 @@
+#!/usr/bin/env python
+# -*- coding: euc-jp -*-
+
+##
+# @file ExecutionContextWorker.py
+# @brief ExecutionContext's state machine worker class
+# @date $Date$
+# @author Noriaki Ando <n-ando at aist.go.jp> and Shinji Kurihara
+#
+# Copyright (C) 2011
+# Noriaki Ando
+# Intelligent Systems Research Institute,
+# National Institute of
+# Advanced Industrial Science and Technology (AIST), Japan
+# All rights reserved.
+#
+# $Id$
+#
+
+import threading
+from omniORB import CORBA, PortableServer
+
+import OpenRTM_aist
+import RTC
+
+
+##
+# @if jp
+# @class PeriodicExecutionContext
+# @brief PeriodicExecutionContext クラス
+#
+# Periodic Sampled Data Processing(周期実行用)ExecutionContextクラス。
+#
+# @since 0.4.0
+#
+# @else
+# @class PeriodicExecutionContext
+# @brief PeriodicExecutionContext class
+#
+# Periodic Sampled Data Processing (for the execution cycles)
+# ExecutionContext class
+#
+# @since 0.4.0
+#
+# @endif
+class ExecutionContextWorker:
+ """
+ """
+
+ ##
+ # @if jp
+ # @brief デフォルトコンストラクタ
+ #
+ # デフォルトコンストラクタ
+ # プロファイルに以下の項目を設定する。
+ # - kind : PERIODIC
+ # - rate : 0.0
+ #
+ # @else
+ # @brief Default Constructor
+ #
+ # Default Constructor
+ # Set the following items to profile.
+ # - kind : PERIODIC
+ # - rate : 0.0
+ #
+ # @endif
+ def __init__(self):
+ self._rtcout = OpenRTM_aist.Manager.instance().getLogbuf("ec_worker")
+ self._running = False
+ self._rtcout.RTC_TRACE("ExecutionContextWorker.__init__")
+ self._ref = None
+ self._comps = []
+ self._addedComps = []
+ self._removedComps = []
+ self._mutex = threading.RLock()
+ self._addedMutex = threading.RLock()
+ self._removedMutex = threading.RLock()
+ return
+
+
+ ##
+ # @if jp
+ # @brief デストラクタ
+ #
+ # デストラクタ
+ #
+ # @else
+ # @brief Destructor
+ #
+ # Destructor
+ #
+ # @endif
+ def __del__(self):
+ self._rtcout.RTC_TRACE("~ExecutionContextWorker.__del__")
+ return
+
+
+ #============================================================
+ # Object reference to EC
+ #============================================================
+ # void setECRef(RTC::ExecutionContextService_ptr ref);
+ def setECRef(self, ref):
+ self._ref = ref
+ return
+
+
+ #RTC::ExecutionContextService_ptr getECRef();
+ def getECRef(self):
+ return self._ref
+
+
+ #============================================================
+ # ExecutionContext
+ #============================================================
+ ##
+ # @if jp
+ # @brief ExecutionContext 実行状態確認関数
+ #
+ # この操作は ExecutionContext が Runnning 状態の場合に true を返す。
+ # Executioncontext が Running の間、当該 Executioncontext に参加し
+ # ている全てのアクティブRTコンポーネントが、ExecutionContext の実
+ # 行種類に応じて実行される。
+ #
+ # @return 状態確認関数(動作中:true、停止中:false)
+ #
+ # @else
+ #
+ # @brief Check for ExecutionContext running state
+ #
+ # This operation shall return true if the context is in the
+ # Running state. While the context is Running, all Active RTCs
+ # participating in the context shall be executed according to the
+ # context’s execution kind.
+ #
+ # @return Check state function (Running:true、Stopping:false)
+ #
+ # @endif
+ # bool isRunning(void);
+ def isRunning(self):
+ self._rtcout.RTC_TRACE("isRunning()")
+ return self._running
+
+
+ ##
+ # @if jp
+ # @brief ExecutionContext の実行を開始
+ #
+ # ExecutionContext の実行状態を Runnning とするためのリクエストを
+ # 発行する。ExecutionContext の状態が遷移すると
+ # ComponentAction::on_startup が呼び出される。参加しているRTコンポー
+ # ネントが、初期化されるまで ExecutionContext を開始することはでき
+ # ない。ExecutionContext は複数回開始/停止を繰り返すことができる。
+ #
+ # @return ReturnCode_t 型のリターンコード
+ #
+ # @else
+ #
+ # @brief Start the ExecutionContext
+ #
+ # Request that the context enter the Running state. Once the
+ # state transition occurs, the ComponentAction::on_startup
+ # operation will be invoked. An execution context may not be
+ # started until the RT-Components that participate in it have
+ # been initialized. An execution context may be started and
+ # stopped multiple times.
+ #
+ # @return The return code of ReturnCode_t type
+ #
+ # @endif
+ # RTC::ReturnCode_t start(void);
+ def start(self):
+ self._rtcout.RTC_TRACE("start()")
+ guard = OpenRTM_aist.ScopedLock(self._mutex)
+ if self._running:
+ del guard
+ self._rtcout.RTC_WARN("ExecutionContext is already running.")
+ return RTC.PRECONDITION_NOT_MET
+
+ # invoke ComponentAction::on_startup for each comps.
+ for comp in self._comps:
+ comp.onStartup()
+
+ self._rtcout.RTC_DEBUG("%d components started.", len(self._comps))
+ # change EC thread state
+ self._running = True
+ del guard
+ return RTC.RTC_OK
+
+
+ ##
+ # @if jp
+ # @brief ExecutionContext の実行を停止
+ #
+ # ExecutionContext の状態を Stopped とするためのリクエストを発行す
+ # る。遷移が発生した場合は、ComponentAction::on_shutdown が呼び出
+ # される。参加しているRTコンポーネントが終了する前に
+ # ExecutionContext を停止する必要がある。ExecutionContext は複数回
+ # 開始/停止を繰り返すことができる。
+ #
+ # @return ReturnCode_t 型のリターンコード
+ #
+ # @else
+ #
+ # @brief Stop the ExecutionContext
+ #
+ # Request that the context enter the Stopped state. Once the
+ # transition occurs, the ComponentAction::on_shutdown operation
+ # will be invoked. An execution context must be stopped before
+ # the RT components that participate in it are finalized. An
+ # execution context may be started and stopped multiple times.
+ #
+ # @return The return code of ReturnCode_t type
+ #
+ # @endif
+ # RTC::ReturnCode_t stop(void);
+ def stop(self):
+ self._rtcout.RTC_TRACE("stop()")
+ guard = OpenRTM_aist.ScopedLock(self._mutex)
+ if not self._running:
+ del guard
+ self._rtcout.RTC_WARN("ExecutionContext is already stopped.")
+ return RTC.PRECONDITION_NOT_MET
+
+ # stop thread
+ self._running = False
+
+ # invoke on_shutdown for each comps.
+ for comp in self._comps:
+ comp.onShutdown()
+
+ del guard
+ return RTC.RTC_OK
+
+
+ ##
+ # @if jp
+ # @brief RTコンポーネントをアクティブ化する
+ #
+ # Inactive 状態にあるRTコンポーネントをActive に遷移させ、アクティ
+ # ブ化する。この操作が呼ばれた結果、on_activate が呼び出される。指
+ # 定したRTコンポーネントが参加者リストに含まれない場合は、
+ # BAD_PARAMETER が返される。指定したRTコンポーネントの状態が
+ # Inactive 以外の場合は、PRECONDITION_NOT_MET が返される。
+ #
+ # @param comp アクティブ化対象RTコンポーネント
+ #
+ # @return ReturnCode_t 型のリターンコード
+ #
+ # @else
+ #
+ # @brief Activate an RT-component
+ #
+ # The given participant RTC is Inactive and is therefore not
+ # being invoked according to the execution context’s execution
+ # kind. This operation shall cause the RTC to transition to the
+ # Active state such that it may subsequently be invoked in this
+ # execution context. The callback on_activate shall be called as
+ # a result of calling this operation. This operation shall not
+ # return until the callback has returned, and shall result in an
+ # error if the callback does.
+ #
+ # @param comp The target RT-Component for activation
+ #
+ # @return The return code of ReturnCode_t type
+ #
+ # @endif
+ # RTC::ReturnCode_t activateComponent(RTC::LightweightRTObject_ptr comp,
+ # RTObjectStateMachine*& rtobj);
+ def activateComponent(self, comp, rtobj):
+ self._rtcout.RTC_TRACE("activateComponent()")
+ guard = OpenRTM_aist.ScopedLock(self._mutex)
+ obj_ = self.findComponent(comp)
+ if not obj_:
+ del guard
+ self._rtcout.RTC_ERROR("Given RTC is not participant of this EC.")
+ return RTC.BAD_PARAMETER
+
+ self._rtcout.RTC_DEBUG("Component found in the EC.")
+ if not obj_.isCurrentState(RTC.INACTIVE_STATE):
+ del guard
+ self._rtcout.RTC_ERROR("State of the RTC is not INACTIVE_STATE.")
+ return RTC.PRECONDITION_NOT_MET
+
+ self._rtcout.RTC_DEBUG("Component is in INACTIVE state. Going to ACTIVE state.")
+ obj_.goTo(RTC.ACTIVE_STATE)
+ rtobj[0] = obj_
+ del guard
+ self._rtcout.RTC_DEBUG("activateComponent() done.")
+ return RTC.RTC_OK
+
+
+ # RTC::ReturnCode_t waitActivateComplete(RTObjectStateMachine*& rtobj,
+ # coil::TimeValue timeout = 1.0,
+ # long int cycle = 1000);
+ def waitActivateComplete(self, rtobj, timeout = 1.0, cycle = 1000):
+ pass
+
+ ##
+ # @if jp
+ # @brief RTコンポーネントを非アクティブ化する
+ #
+ # Inactive 状態にあるRTコンポーネントを非アクティブ化し、Inactive
+ # に遷移させる。この操作が呼ばれた結果、on_deactivate が呼び出され
+ # る。指定したRTコンポーネントが参加者リストに含まれない場合は、
+ # BAD_PARAMETER が返される。指定したRTコンポーネントの状態が
+ # Active 以外の場合は、PRECONDITION_NOT_MET が返される。
+ #
+ # @param comp 非アクティブ化対象RTコンポーネント
+ #
+ # @return ReturnCode_t 型のリターンコード
+ #
+ # @else
+ #
+ # @brief Deactivate an RT-component
+ #
+ # The given RTC is Active in the execution context. Cause it to
+ # transition to the Inactive state such that it will not be
+ # subsequently invoked from the context unless and until it is
+ # activated again. The callback on_deactivate shall be called as
+ # a result of calling this operation. This operation shall not
+ # return until the callback has returned, and shall result in an
+ # error if the callback does.
+ #
+ # @param comp The target RT-Component for deactivate
+ #
+ # @return The return code of ReturnCode_t type
+ #
+ # @endif
+ # RTC::ReturnCode_t deactivateComponent(RTC::LightweightRTObject_ptr comp,
+ # RTObjectStateMachine*& rtobj);
+ def deactivateComponent(self, comp, rtobj):
+ self._rtcout.RTC_TRACE("deactivateComponent()")
+ guard = OpenRTM_aist.ScopedLock(self._mutex)
+
+ rtobj[0] = self.findComponent(comp)
+ if not rtobj[0]:
+ del guard
+ self._rtcout.RTC_ERROR("Given RTC is not participant of this EC.")
+ return RTC.BAD_PARAMETER
+
+ if not rtobj[0].isCurrentState(RTC.ACTIVE_STATE):
+ del guard
+ self._rtcout.RTC_ERROR("State of the RTC is not ACTIVE_STATE.")
+ return RTC.PRECONDITION_NOT_MET
+
+ rtobj[0].goTo(RTC.INACTIVE_STATE)
+ del guard
+ return RTC.RTC_OK
+
+
+ # RTC::ReturnCode_t waitDeactivateComplete(RTObjectStateMachine*& rtobj,
+ # coil::TimeValue timeout = 1.0,
+ # long int cycle = 1000);
+ def waitDeactivateComplete(self, rtobj, timeout = 1.0, cycle = 1000):
+ pass
+
+
+ ##
+ # @if jp
+ # @brief RTコンポーネントをリセットする
+ #
+ # Error 状態のRTコンポーネントの復帰を試みる。この操作が呼ばれた結
+ # 果、on_reset が呼び出される。指定したRTコンポーネントが参加者リ
+ # ストに含まれない場合は、BAD_PARAMETER が返される。指定したRTコン
+ # ポーネントの状態が Error 以外の場合は、PRECONDITION_NOT_MET が返
+ # される。
+ #
+ # @param comp リセット対象RTコンポーネント
+ #
+ # @return ReturnCode_t 型のリターンコード
+ #
+ # @else
+ #
+ # @brief Reset the RT-component
+ #
+ # Attempt to recover the RTC when it is in Error. The
+ # ComponentAction::on_reset callback shall be invoked. This
+ # operation shall not return until the callback has returned, and
+ # shall result in an error if the callback does. If possible, the
+ # RTC developer should implement that callback such that the RTC
+ # may be returned to a valid state.
+ #
+ # @param comp The target RT-Component for reset
+ #
+ # @return The return code of ReturnCode_t type
+ #
+ # @endif
+ # RTC::ReturnCode_t resetComponent(RTC::LightweightRTObject_ptr com,
+ # RTObjectStateMachine*& rtobj);
+ def resetComponent(self, comp, rtobj):
+ self._rtcout.RTC_TRACE("resetComponent()")
+ guard = OpenRTM_aist.ScopedLock(self._mutex)
+
+ rtobj[0] = self.findComponent(comp)
+ if not rtobj[0]:
+ del guard
+ self._rtcout.RTC_ERROR("Given RTC is not participant of this EC.")
+ return RTC.BAD_PARAMETER
+
+ if not rtobj[0].isCurrentState(RTC.ERROR_STATE):
+ del guard
+ self._rtcout.RTC_ERROR("State of the RTC is not ERROR_STATE.")
+ return RTC.PRECONDITION_NOT_MET
+
+ rtobj[0].goTo(RTC.INACTIVE_STATE)
+ del guard
+ return RTC.RTC_OK
+
+
+ # RTC::ReturnCode_t waitResetComplete(RTObjectStateMachine*& rtobj,
+ # coil::TimeValue timeout = 1.0,
+ # long int cycle = 1000);
+ def waitResetComplete(self, rtobj, timeout = 1.0, cycle = 1000):
+ pass
+
+
+ ##
+ # @if jp
+ # @brief RTコンポーネントの状態を取得する
+ #
+ # 指定したRTコンポーネントの状態(LifeCycleState)を取得する。指定し
+ # たRTコンポーネントが参加者リストに含まれない場合は、
+ # UNKNOWN_STATE が返される。
+ #
+ # @param comp 状態取得対象RTコンポーネント
+ #
+ # @return 現在の状態(LifeCycleState)
+ #
+ # @else
+ #
+ # @brief Get RT-component's state
+ #
+ # This operation shall report the LifeCycleState of the given
+ # participant RTC. UNKNOWN_STATE will be returned, if the given
+ # RT-Component is not inclued in the participant list.
+ #
+ # @param comp The target RT-Component to get the state
+ #
+ # @return The current state of the target RT-Component(LifeCycleState)
+ #
+ # @endif
+ # RTC::LifeCycleState getComponentState(RTC::LightweightRTObject_ptr comp);
+ def getComponentState(self, comp):
+ self._rtcout.RTC_TRACE("getComponentState()")
+ guard = OpenRTM_aist.ScopedLock(self._mutex)
+ rtobj_ = self.findComponent(comp)
+ if not rtobj_:
+ del guard
+ self._rtcout.RTC_WARN("Given RTC is not participant of this EC.")
+ return RTC.CREATED_STATE
+
+ state_ = rtobj_.getState()
+ self._rtcout.RTC_DEBUG("getComponentState() = %s done", self.getStateString(state_))
+ return state_
+
+
+ # const char* getStateString(RTC::LifeCycleState state)
+ def getStateString(self, state):
+ st = ["CREATED_STATE",
+ "INACTIVE_STATE",
+ "ACTIVE_STATE",
+ "ERROR_STATE"]
+
+ f = lambda x: st[x._v] if x >= RTC.CREATED_STATE and x <= RTC.ERROR_STATE else ""
+ return f(state)
+
+ ##
+ # @if jp
+ # @brief RTコンポーネントを追加する
+ #
+ # 指定したRTコンポーネントを参加者リストに追加する。追加されたRTコ
+ # ンポーネントは attach_context が呼ばれ、Inactive 状態に遷移する。
+ # 指定されたRTコンポーネントがnullの場合は、BAD_PARAMETER が返され
+ # る。指定されたRTコンポーネントが DataFlowComponent 以外の場合は、
+ # BAD_PARAMETER が返される。
+ #
+ # @param comp 追加対象RTコンポーネント
+ #
+ # @return ReturnCode_t 型のリターンコード
+ #
+ # @else
+ #
+ # @brief Add an RT-component
+ #
+ # The operation causes the given RTC to begin participating in
+ # the execution context. The newly added RTC will receive a call
+ # to LightweightRTComponent::attach_context and then enter the
+ # Inactive state. BAD_PARAMETER will be invoked, if the given
+ # RT-Component is null or if the given RT-Component is other than
+ # DataFlowComponent.
+ #
+ # @param comp The target RT-Component for add
+ #
+ # @return The return code of ReturnCode_t type
+ #
+ # @endif
+ # RTC::ReturnCode_t addComponent(RTC::LightweightRTObject_ptr comp);
+ def addComponent(self, comp):
+ self._rtcout.RTC_TRACE("addComponent()")
+ if CORBA.is_nil(comp):
+ self._rtcout.RTC_ERROR("nil reference is given.")
+ return RTC.BAD_PARAMETER
+
+ try:
+ guard = OpenRTM_aist.ScopedLock(self._addedMutex)
+ ec_ = self.getECRef()
+ id_ = comp.attach_context(ec_)
+ self._addedComps.append(OpenRTM_aist.RTObjectStateMachine(id_, comp))
+ del guard
+ except:
+ del guard
+ self._rtcout.RTC_ERROR("addComponent() failed.")
+ return RTC.RTC_ERROR
+
+ self._rtcout.RTC_DEBUG("addComponent() succeeded.")
+ return RTC.RTC_OK
+
+
+ ##
+ # @if jp
+ # @brief コンポーネントをバインドする。
+ #
+ # コンポーネントをバインドする。
+ #
+ # @param rtc RTコンポーネント
+ # @return ReturnCode_t 型のリターンコード
+ # @else
+ # @brief Bind the component.
+ #
+ # Bind the component.
+ #
+ # @param rtc RT-Component's instances
+ # @return The return code of ReturnCode_t type
+ # @endif
+ # RTC::ReturnCode_t bindComponent(RTC::RTObject_impl* rtc);
+ def bindComponent(self, rtc):
+ self._rtcout.RTC_TRACE("bindComponent()")
+ guard = OpenRTM_aist.ScopedLock(self._mutex)
+ if not rtc:
+ del guard
+ self._rtcout.RTC_ERROR("NULL pointer is given.")
+ return RTC.BAD_PARAMETER
+
+ ec_ = self.getECRef()
+ id_ = rtc.bindContext(ec_)
+ if id_ < 0 or id_ > OpenRTM_aist.ECOTHER_OFFSET:
+ # id should be owned context id < ECOTHER_OFFSET
+ del guard
+ self._rtcout.RTC_ERROR("bindContext returns invalid id: %d", id_)
+ return RTC.RTC_ERROR
+
+ self._rtcout.RTC_DEBUG("bindContext returns id = %d", id_)
+
+ # rtc is owner of this EC
+ comp_ = rtc.getObjRef()
+ # RTObjectStateMachine o(id, comp);
+ self._comps.append(OpenRTM_aist.RTObjectStateMachine(id_, comp_))
+ del guard
+ self._rtcout.RTC_DEBUG("bindComponent() succeeded.")
+ return RTC.RTC_OK
+
+
+ ##
+ # @if jp
+ # @brief RTコンポーネントを参加者リストから削除する
+ #
+ # 指定したRTコンポーネントを参加者リストから削除する。削除された
+ # RTコンポーネントは detach_context が呼ばれる。指定されたRTコンポー
+ # ネントが参加者リストに登録されていない場合は、BAD_PARAMETER が返
+ # される。
+ #
+ # @param comp 削除対象RTコンポーネント
+ #
+ # @return ReturnCode_t 型のリターンコード
+ #
+ # @else
+ #
+ # @brief Remove the RT-Component from participant list
+ #
+ # This operation causes a participant RTC to stop participating in the
+ # execution context.
+ # The removed RTC will receive a call to
+ # LightweightRTComponent::detach_context.
+ # BAD_PARAMETER will be returned, if the given RT-Component is not
+ # participating in the participant list.
+ #
+ # @param comp The target RT-Component for delete
+ #
+ # @return The return code of ReturnCode_t type
+ #
+ # @endif
+ # RTC::ReturnCode_t removeComponent(RTC::LightweightRTObject_ptr comp);
+ def removeComponent(self, comp):
+ self._rtcout.RTC_TRACE("removeComponent()")
+ if CORBA.is_nil(comp):
+ self._rtcout.RTC_ERROR("nil reference is given.")
+ return RTC.BAD_PARAMETER
+
+
+ guard = OpenRTM_aist.ScopedLock(self._mutex)
+ rtobj_ = self.findComponent(comp)
+ del guard
+
+ if not rtobj_:
+ self._rtcout.RTC_ERROR("no RTC found in this context.")
+ return RTC.BAD_PARAMETER
+
+ guard = OpenRTM_aist.ScopedLock(self._removedMutex)
+ self._removedComps.append(rtobj_)
+ del guard
+ return RTC.RTC_OK
+
+
+ # RTObjectStateMachine* findComponent(RTC::LightweightRTObject_ptr comp);
+ def findComponent(self, comp):
+ for comp_ in self._comps:
+ if comp_.isEquivalent(comp):
+ return comp_
+
+ return None
+
+
+ # bool isAllCurrentState(RTC::LifeCycleState state);
+ def isAllCurrentState(self, state):
+ guard = OpenRTM_aist.ScopedLock(self._mutex)
+ for comp in self._comps:
+ if not comp.isCurrentState(state):
+ del guard
+ return False
+
+ del guard
+ return True
+
+
+ # bool isAllNextState(RTC::LifeCycleState state);
+ def isAllNextState(self, state):
+ guard = OpenRTM_aist.ScopedLock(self._mutex)
+ for comp in self._comps:
+ if not comp.isNextState(state):
+ del guard
+ return False
+
+ del guard
+ return True
+
+
+ # bool isOneOfCurrentState(RTC::LifeCycleState state);
+ def isOneOfCurrentState(self, state):
+ guard = OpenRTM_aist.ScopedLock(self._mutex)
+ for comp in self._comps:
+ if comp.isCurrentState(state):
+ del guard
+ return True
+
+ del guard
+ return False
+
+
+ # bool isOneOfNextState(RTC::LifeCycleState state);
+ def isOneOfNextState(self, state):
+ guard = OpenRTM_aist.ScopedLock(self._mutex)
+ for comp in self._comps:
+ if comp.isNextState(state):
+ del guard
+ return True
+
+ del guard
+ return False
+
+
+ # void invokeWorker();
+ def invokeWorker(self):
+ self._rtcout.RTC_PARANOID("invokeWorker()")
+ # m_comps never changes its size here
+ len_ = len(self._comps)
+
+ for i in range(len_):
+ self._comps[i].workerPreDo()
+
+ for i in range(len_):
+ self._comps[i].workerDo()
+
+ for i in range(len_):
+ self._comps[i].workerPostDo()
+
+ self.updateComponentList()
+ return
+
+
+ # void invokeWorkerPreDo();
+ def invokeWorkerPreDo(self):
+ self._rtcout.RTC_PARANOID("invokeWorkerPreDo()")
+ # m_comps never changes its size here
+ for comp in self._comps:
+ comp.workerPreDo()
+ return
+
+ # void invokeWorkerDo();
+ def invokeWorkerDo(self):
+ self._rtcout.RTC_PARANOID("invokeWorkerDo()")
+ # m_comps never changes its size here
+ for comp in self._comps:
+ comp.workerDo()
+ return
+
+ # void invokeWorkerPostDo();
+ def invokeWorkerPostDo(self):
+ self._rtcout.RTC_PARANOID("invokeWorkerPostDo()")
+ # m_comps never changes its size here
+ for comp in self._comps:
+ comp.workerPostDo()
+ # m_comps might be changed here
+ self.updateComponentList()
+ return
+
+ # void updateComponentList();
+ def updateComponentList(self):
+ guard = OpenRTM_aist.ScopedLock(self._mutex)
+ # adding component
+ guard_added = OpenRTM_aist.ScopedLock(self._addedMutex)
+ for comp in self._addedComps:
+ self._comps.append(comp)
+ self._rtcout.RTC_TRACE("Component added.")
+
+ self._addedComps = []
+ del guard_added
+
+ # removing component
+ guard_removed = OpenRTM_aist.ScopedLock(self._removedMutex)
+ for comp in self._removedComps:
+ lwrtobj_ = comp.getRTObject()
+ lwrtobj_.detach_context(comp.getExecutionContextHandle())
+ idx_ = -1
+ try:
+ idx_ = self._comps.index(comp)
+ except:
+ idx_ = -1
+
+ if idx_ >= 0:
+ del self._comps[idx_]
+ self._rtcout.RTC_TRACE("Component deleted.")
+
+ self._removedComps = []
+ return
Added: branches/work/OpenRTM-aist-Python/OpenRTM_aist/test/test_ExecutionContextWorker.py
===================================================================
--- branches/work/OpenRTM-aist-Python/OpenRTM_aist/test/test_ExecutionContextWorker.py (rev 0)
+++ branches/work/OpenRTM-aist-Python/OpenRTM_aist/test/test_ExecutionContextWorker.py 2012-03-13 05:30:45 UTC (rev 525)
@@ -0,0 +1,242 @@
+#!/usr/bin/env python
+# -*- coding: euc-jp -*-
+
+##
+# @file test_ExecutionContextWorker.py
+# @brief test for ExecutionContext's state machine worker class
+# @date $Date$
+# @author Shinji Kurihara
+#
+# Copyright (C) 2011
+# Noriaki Ando
+# Intelligent Systems Research Institute,
+# National Institute of
+# Advanced Industrial Science and Technology (AIST), Japan
+# All rights reserved.
+#
+# $Id$
+#
+
+import sys
+sys.path.insert(1,"../")
+sys.path.insert(1,"../RTM_IDL")
+
+import time
+import unittest
+
+from ExecutionContextWorker import *
+import OpenRTM__POA, RTC__POA, RTC
+import OpenRTM_aist
+
+testcomp_spec = ["implementation_id", "TestComp",
+ "type_name", "TestComp",
+ "description", "Test example component",
+ "version", "1.0",
+ "vendor", "Shinji Kurihara, AIST",
+ "category", "example",
+ "activity_type", "DataFlowComponent",
+ "max_instance", "10",
+ "language", "Python",
+ "lang_type", "compile",
+ ""]
+
+class TestComp(OpenRTM_aist.DataFlowComponentBase):
+ def __init_(self, manager):
+ OpenRTM_aist.DataFlowComponentBase.__init__(self, manager)
+
+
+def TestCompInit(manager):
+ global com
+ profile = OpenRTM_aist.Properties(defaults_str=configsample_spec)
+ manager.registerFactory(profile,
+ TestComp,
+ OpenRTM_aist.Delete)
+
+
+class MyEC(OpenRTM__POA.ExtTrigExecutionContextService):
+ def __init__(self):
+ self._ref = self._this()
+ return
+
+class MyEC3(OpenRTM_aist.ExecutionContextBase,
+ RTC__POA.ExecutionContextService,
+ OpenRTM_aist.Task):
+
+ def __init__(self, name):
+ OpenRTM_aist.ExecutionContextBase.__init__(self, name)
+ OpenRTM_aist.Task.__init__(self)
+ self.setObjRef(self._this())
+ self._svc = False
+ return
+
+ def __del__(self, Task=OpenRTM_aist.Task):
+ self._svc = False
+ return
+
+ def start(self):
+ return OpenRTM_aist.ExecutionContextBase.start(self)
+
+ def stop(self):
+ self._svc = False
+ return
+
+ def open(self, *args):
+ self.activate()
+ return 0
+
+ def onStarting(self):
+ self._svc = True
+ self.open(0)
+ return RTC.RTC_OK
+
+
+ def svc(self):
+ while self._svc:
+ OpenRTM_aist.ExecutionContextBase.invokeWorkerPreDo(self)
+ OpenRTM_aist.ExecutionContextBase.invokeWorkerDo(self)
+ OpenRTM_aist.ExecutionContextBase.invokeWorkerPostDo(self)
+
+ return 0
+
+ def onGetRate(self, rate):
+ return rate
+
+class TestExecutionContextWorker(unittest.TestCase):
+
+ def setUp(self):
+ self._ecworker = ExecutionContextWorker()
+
+ def tearDown(self):
+ OpenRTM_aist.Manager.instance().shutdownManager()
+ return
+
+ def test_setGetECRef(self):
+ ec_ = MyEC()
+ ref_ = ec_._ref
+ self._ecworker.setECRef(ref_)
+ self.assertEqual(ref_,self._ecworker.getECRef())
+
+ return
+
+
+ def test_startStopIsRunning(self):
+ self.assertEqual(RTC.RTC_OK, self._ecworker.start())
+ self.assertEqual(RTC.PRECONDITION_NOT_MET, self._ecworker.start())
+ self.assertEqual(True, self._ecworker.isRunning())
+ self.assertEqual(RTC.RTC_OK, self._ecworker.stop())
+ self.assertEqual(False, self._ecworker.isRunning())
+ self.assertEqual(RTC.PRECONDITION_NOT_MET, self._ecworker.stop())
+ return
+
+ def test_actDeactResetState(self):
+ mgr_ = OpenRTM_aist.Manager.instance()
+ mgr_.activateManager()
+ profile = OpenRTM_aist.Properties(defaults_str=testcomp_spec)
+ mgr_.registerFactory(profile,
+ TestComp,
+ OpenRTM_aist.Delete)
+ comp = mgr_.createComponent("TestComp")
+ ec_ = MyEC3("test")
+ self._ecworker.setECRef(ec_._this())
+ self.assertEqual(RTC.RTC_OK,self._ecworker.bindComponent(comp))
+ self._ecworker.start()
+ rtobj_ = [None]
+
+ # INACTIVE -> ACTIVE
+ self.assertEqual(RTC.RTC_OK, self._ecworker.activateComponent(comp.getObjRef(),rtobj_))
+ self.assertEqual(False, self._ecworker.isAllCurrentState(RTC.ACTIVE_STATE))
+ self.assertEqual(True, self._ecworker.isAllNextState(RTC.ACTIVE_STATE))
+ self.assertEqual(False, self._ecworker.isOneOfCurrentState(RTC.ACTIVE_STATE))
+ self._ecworker.invokeWorker()
+ self.assertEqual(RTC.ACTIVE_STATE, self._ecworker.getComponentState(comp.getObjRef()))
+ self.assertEqual(True, self._ecworker.isAllCurrentState(RTC.ACTIVE_STATE))
+ self.assertEqual(True, self._ecworker.isOneOfCurrentState(RTC.ACTIVE_STATE))
+
+ # ACTIVE -> INACTIVE
+ self.assertEqual(RTC.RTC_OK, self._ecworker.deactivateComponent(comp.getObjRef(),rtobj_))
+ self.assertEqual(False, self._ecworker.isAllCurrentState(RTC.INACTIVE_STATE))
+ self.assertEqual(True, self._ecworker.isOneOfNextState(RTC.INACTIVE_STATE))
+ self.assertEqual(True, self._ecworker.isAllNextState(RTC.INACTIVE_STATE))
+ self._ecworker.invokeWorker()
+ self.assertEqual(RTC.INACTIVE_STATE, self._ecworker.getComponentState(comp.getObjRef()))
+ self.assertEqual(True, self._ecworker.isAllCurrentState(RTC.INACTIVE_STATE))
+
+ # INACTIVE -> ACTIVE -> ERROR
+ self.assertEqual(RTC.RTC_OK, self._ecworker.activateComponent(comp.getObjRef(),rtobj_))
+ self._ecworker.invokeWorker()
+ rtobj_[0] = self._ecworker.findComponent(comp.getObjRef())
+ rtobj_[0].goTo(RTC.ERROR_STATE)
+ self.assertEqual(True, self._ecworker.isOneOfNextState(RTC.ERROR_STATE))
+ self._ecworker.invokeWorker()
+ self.assertEqual(RTC.ERROR_STATE, self._ecworker.getComponentState(comp.getObjRef()))
+
+ # ERROR -> INACTIVE
+ self.assertEqual(RTC.RTC_OK, self._ecworker.resetComponent(comp.getObjRef(),rtobj_))
+ self._ecworker.invokeWorker()
+ self.assertEqual(RTC.INACTIVE_STATE, self._ecworker.getComponentState(comp.getObjRef()))
+ self.assertEqual(True, self._ecworker.isAllCurrentState(RTC.INACTIVE_STATE))
+ self._ecworker.stop()
+ return
+
+ def waitActivateComplete(self):
+ # No implementation.
+ return
+
+ def waitDeactivateComplete(self):
+ # No implementation.
+ return
+
+ def waitResetComplete(self):
+ # No implementation.
+ return
+
+ def test_getStateString(self):
+ self.assertEqual("CREATED_STATE", self._ecworker.getStateString(RTC.CREATED_STATE))
+ self.assertEqual("INACTIVE_STATE", self._ecworker.getStateString(RTC.INACTIVE_STATE))
+ self.assertEqual("ACTIVE_STATE", self._ecworker.getStateString(RTC.ACTIVE_STATE))
+ self.assertEqual("ERROR_STATE", self._ecworker.getStateString(RTC.ERROR_STATE))
+ return
+
+ def test_addRemoveComponent(self):
+ mgr_ = OpenRTM_aist.Manager.instance()
+ mgr_.activateManager()
+ profile = OpenRTM_aist.Properties(defaults_str=testcomp_spec)
+
+ mgr_.registerFactory(profile,
+ TestComp,
+ OpenRTM_aist.Delete)
+
+ comp = mgr_.createComponent("TestComp")
+ ec_ = MyEC()
+ self._ecworker.setECRef(ec_._ref)
+ self.assertEqual(RTC.RTC_OK, self._ecworker.addComponent(comp.getObjRef()))
+ self._ecworker.invokeWorker()
+ self.assertEqual(RTC.BAD_PARAMETER, self._ecworker.removeComponent(None))
+ self.assertEqual(RTC.RTC_OK, self._ecworker.removeComponent(comp.getObjRef()))
+ return
+
+ def test_invokeWorker(self):
+ mgr_ = OpenRTM_aist.Manager.instance()
+ mgr_.activateManager()
+ profile = OpenRTM_aist.Properties(defaults_str=testcomp_spec)
+
+ mgr_.registerFactory(profile,
+ TestComp,
+ OpenRTM_aist.Delete)
+
+ comp = mgr_.createComponent("TestComp")
+ ec_ = MyEC()
+ self._ecworker.setECRef(ec_._ref)
+ self.assertEqual(RTC.RTC_OK, self._ecworker.addComponent(comp.getObjRef()))
+ self._ecworker.invokeWorkerPreDo()
+ self._ecworker.invokeWorkerDo()
+ self._ecworker.invokeWorkerPostDo()
+ self._ecworker.updateComponentList()
+ self.assertEqual(RTC.BAD_PARAMETER, self._ecworker.removeComponent(None))
+ self.assertEqual(RTC.RTC_OK, self._ecworker.removeComponent(comp.getObjRef()))
+ return
+
+
+############### test #################
+if __name__ == '__main__':
+ unittest.main()
openrtm-commit メーリングリストの案内