PeriodicExecutionContext.h
Go to the documentation of this file.
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


openrtm_aist
Author(s): Noriaki Ando
autogenerated on Thu Aug 27 2015 14:16:38