OpenRTM
1.0.0
|
00001 // -*- C++ -*- 00020 #ifndef RTC_PERIODICEXECUTIONCONTEXT_H 00021 #define RTC_PERIODICEXECUTIONCONTEXT_H 00022 00023 #include <coil/Task.h> 00024 #include <coil/Mutex.h> 00025 #include <coil/Condition.h> 00026 #include <vector> 00027 #include <iostream> 00028 00029 #include <rtm/RTC.h> 00030 #include <rtm/idl/RTCSkel.h> 00031 #include <rtm/idl/OpenRTMSkel.h> 00032 #include <rtm/Manager.h> 00033 #include <rtm/StateMachine.h> 00034 #include <rtm/ExecutionContextBase.h> 00035 00036 #define NUM_OF_LIFECYCLESTATE 4 00037 00038 #ifdef WIN32 00039 #pragma warning( disable : 4290 ) 00040 #endif 00041 00042 namespace RTC 00043 { 00064 class PeriodicExecutionContext 00065 : public virtual ExecutionContextBase, 00066 public coil::Task 00067 { 00068 typedef coil::Guard<coil::Mutex> Guard; 00069 public: 00089 PeriodicExecutionContext(); 00090 00112 PeriodicExecutionContext(OpenRTM::DataFlowComponent_ptr owner, 00113 double rate = 1000.0); 00114 00128 virtual ~PeriodicExecutionContext(void); 00129 00149 virtual ExecutionContextService_ptr getObjRef(void) {return m_ref;} 00150 00175 virtual int open(void *args); 00176 00196 virtual int svc(void); 00197 00225 virtual int close(unsigned long flags); 00226 00227 //============================================================ 00228 // ExecutionContext 00229 //============================================================ 00254 virtual CORBA::Boolean is_running(void) 00255 throw (CORBA::SystemException); 00256 00284 virtual ReturnCode_t start(void) 00285 throw (CORBA::SystemException); 00286 00313 virtual ReturnCode_t stop(void) 00314 throw (CORBA::SystemException); 00315 00336 virtual CORBA::Double get_rate(void) 00337 throw (CORBA::SystemException); 00338 00368 virtual ReturnCode_t set_rate(CORBA::Double rate) 00369 throw (CORBA::SystemException); 00370 00404 virtual ReturnCode_t activate_component(LightweightRTObject_ptr comp) 00405 throw (CORBA::SystemException); 00406 00439 virtual ReturnCode_t deactivate_component(LightweightRTObject_ptr comp) 00440 throw (CORBA::SystemException); 00441 00473 virtual ReturnCode_t reset_component(LightweightRTObject_ptr comp) 00474 throw (CORBA::SystemException); 00475 00502 virtual LifeCycleState get_component_state(LightweightRTObject_ptr comp) 00503 throw (CORBA::SystemException); 00504 00524 virtual ExecutionKind get_kind(void) 00525 throw (CORBA::SystemException); 00526 00558 virtual ReturnCode_t add_component(LightweightRTObject_ptr comp) 00559 throw (CORBA::SystemException); 00560 00578 virtual RTC::ReturnCode_t bindComponent(RTObject_impl* rtc); 00579 00610 virtual ReturnCode_t remove_component(LightweightRTObject_ptr comp) 00611 throw (CORBA::SystemException); 00612 00632 virtual ExecutionContextProfile* get_profile(void) 00633 throw (CORBA::SystemException); 00634 00635 protected: 00636 //============================================================ 00637 // DFPBase 00638 //============================================================ 00639 typedef LifeCycleState ExecContextState; 00640 /* 00641 enum ExecContextState 00642 { 00643 INACTIVE_STATE, 00644 ACTIVE_STATE, 00645 ERROR_STATE, 00646 }; 00647 */ 00648 typedef RTC_Utils::StateHolder<ExecContextState> ECStates; 00649 00670 class DFPBase 00671 { 00672 public: 00673 00691 DFPBase(RTC::ExecutionContextHandle_t id) 00692 : ec_id(id), m_sm(NUM_OF_LIFECYCLESTATE) 00693 { 00694 m_sm.setListener(this); 00695 m_sm.setEntryAction (ACTIVE_STATE, &DFPBase::on_activated); 00696 m_sm.setDoAction (ACTIVE_STATE, &DFPBase::on_execute); 00697 m_sm.setPostDoAction(ACTIVE_STATE, &DFPBase::on_state_update); 00698 m_sm.setExitAction (ACTIVE_STATE, &DFPBase::on_deactivated); 00699 m_sm.setEntryAction (ERROR_STATE, &DFPBase::on_aborting); 00700 m_sm.setDoAction (ERROR_STATE, &DFPBase::on_error); 00701 m_sm.setExitAction (ERROR_STATE, &DFPBase::on_reset); 00702 00703 ECStates st; 00704 st.prev = INACTIVE_STATE; 00705 st.curr = INACTIVE_STATE; 00706 st.next = INACTIVE_STATE; 00707 m_sm.setStartState(st); 00708 m_sm.goTo(INACTIVE_STATE); 00709 } 00710 00724 virtual ~DFPBase(void){} 00725 00742 virtual void on_startup(void) = 0; 00743 00760 virtual void on_shutdown(void) = 0; 00761 00783 virtual void on_activated(const ECStates& st) = 0; 00784 00806 virtual void on_deactivated(const ECStates& st) = 0; 00807 00829 virtual void on_aborting(const ECStates& st) = 0; 00830 00856 virtual void on_error(const ECStates& st) = 0; 00857 00883 virtual void on_reset(const ECStates& st) = 0; 00884 00911 virtual void on_execute(const ECStates& st) = 0; 00912 00939 virtual void on_state_update(const ECStates& st) = 0; 00940 00958 virtual void on_rate_changed(void) = 0; 00959 00978 virtual void worker(void) {return m_sm.worker();} 00979 00997 virtual ExecContextState get_state(void){ return m_sm.getState();} 00998 01006 ExecutionContextHandle_t ec_id; 01007 01015 RTC_Utils::StateMachine<ExecContextState, DFPBase> m_sm; 01016 }; 01017 01018 //============================================================ 01019 // DFP 01020 //============================================================ 01046 template <class Object> 01047 class DFP 01048 : public DFPBase 01049 { 01050 public: 01070 DFP(Object obj, ExecutionContextHandle_t id) 01071 : DFPBase(id), m_obj(obj), m_active(true) 01072 { 01073 } 01074 01090 void on_startup(void) 01091 { 01092 m_obj->on_startup(ec_id); 01093 } 01094 01110 void on_shutdown(void) 01111 { 01112 m_obj->on_shutdown(ec_id); 01113 } 01114 01137 void on_activated(const ECStates& st) 01138 { 01139 if (m_obj->on_activated(ec_id) != RTC::RTC_OK) 01140 { 01141 m_sm.goTo(ERROR_STATE); 01142 return; 01143 } 01144 return; 01145 } 01146 01167 void on_deactivated(const ECStates& st) 01168 { 01169 m_obj->on_deactivated(ec_id); 01170 } 01171 01191 void on_aborting(const ECStates& st) 01192 { 01193 m_obj->on_aborting(ec_id); 01194 } 01195 01215 void on_error(const ECStates& st) 01216 { 01217 m_obj->on_error(ec_id); 01218 } 01219 01239 void on_reset(const ECStates& st) 01240 { 01241 if (m_obj->on_reset(ec_id) != RTC::RTC_OK) 01242 { 01243 m_sm.goTo(ERROR_STATE); 01244 return; 01245 } 01246 return; 01247 } 01248 01274 void on_execute(const ECStates& st) 01275 { 01276 if (m_obj->on_execute(ec_id) != RTC::RTC_OK) 01277 { 01278 m_sm.goTo(ERROR_STATE); 01279 return; 01280 } 01281 return; 01282 } 01283 01309 void on_state_update(const ECStates& st) 01310 { 01311 if (m_obj->on_state_update(ec_id) != RTC::RTC_OK) 01312 { 01313 m_sm.goTo(ERROR_STATE); 01314 return; 01315 } 01316 return; 01317 } 01318 01336 void on_rate_changed(void) 01337 { 01338 m_obj->on_rate_changed(ec_id); 01339 } 01340 01348 Object m_obj; 01349 01357 bool m_active; 01358 }; 01359 01367 struct Comp 01368 { 01369 Comp(LightweightRTObject_ptr ref, OpenRTM::DataFlowComponent_ptr dfp, 01370 ExecutionContextHandle_t id) 01371 : _ref(LightweightRTObject::_duplicate(ref)), 01372 _sm(OpenRTM::DataFlowComponent::_duplicate(dfp), id) 01373 { 01374 } 01375 ~Comp(void) 01376 { 01377 } 01378 Comp(const Comp& comp) 01379 : _ref(comp._ref), _sm(comp._sm.m_obj, comp._sm.ec_id) 01380 { 01381 } 01382 Comp& operator=(const Comp& comp) 01383 { 01384 _ref = comp._ref; 01385 _sm.m_obj = comp._sm.m_obj; 01386 _sm.ec_id = comp._sm.ec_id; 01387 return *this; 01388 } 01389 LightweightRTObject_var _ref; 01390 DFP<OpenRTM::DataFlowComponent_var> _sm; 01391 }; 01392 01400 struct find_comp 01401 { 01402 LightweightRTObject_var m_comp; 01403 find_comp(LightweightRTObject_ptr comp) 01404 : m_comp(LightweightRTObject::_duplicate(comp)) {} 01405 bool operator()(Comp& comp) 01406 { 01407 return comp._ref->_is_equivalent(m_comp); 01408 } 01409 }; 01410 01418 struct invoke_on_startup 01419 { 01420 void operator()(Comp& comp) 01421 { 01422 comp._sm.on_startup(); 01423 } 01424 }; 01425 01433 struct invoke_on_shutdown 01434 { 01435 void operator()(Comp& comp) 01436 { 01437 comp._sm.on_shutdown(); 01438 } 01439 }; 01440 01448 struct invoke_on_rate_changed 01449 { 01450 void operator()(Comp& comp) 01451 { 01452 comp._sm.on_rate_changed(); 01453 } 01454 }; 01455 01463 struct invoke_worker 01464 { 01465 void operator()(Comp& comp) 01466 { 01467 comp._sm.worker(); 01468 } 01469 }; 01470 01478 std::vector<Comp> m_comps; 01479 typedef std::vector<Comp>::iterator CompItr; 01480 01488 Logger rtclog; 01489 01499 bool m_running; 01500 01508 bool m_svc; 01509 01517 struct Worker 01518 { 01519 Worker() : cond_(mutex_), running_(false) {}; 01520 coil::Mutex mutex_; 01521 coil::Condition<coil::Mutex> cond_; 01522 bool running_; 01523 }; 01524 01532 Worker m_worker; 01533 01541 ExecutionContextProfile m_profile; 01542 coil::Mutex m_profileMutex; 01543 01551 coil::TimeValue m_period; 01552 01560 ExecutionContextService_var m_ref; 01561 01570 bool m_nowait; 01571 01572 class find_participant 01573 { 01574 RTObject_var m_comp; 01575 public: 01576 find_participant(RTObject_ptr comp) 01577 : m_comp(RTObject::_duplicate(comp)) {} 01578 bool operator()(RTObject_ptr comp) 01579 { 01580 return m_comp->_is_equivalent(comp); 01581 } 01582 }; 01583 }; // class PeriodicExecutionContext 01584 }; // namespace RTC 01585 01586 #ifdef WIN32 01587 #pragma warning( default : 4290 ) 01588 #endif 01589 01590 01591 extern "C" 01592 { 01600 void PeriodicExecutionContextInit(RTC::Manager* manager); 01601 }; 01602 01603 #endif // RTC_PERIODICEXECUTIONCONTEXT_H