00001
00020 #ifndef PeriodicExecutionContext_h
00021 #define PeriodicExecutionContext_h
00022
00023 #include <rtm/RTC.h>
00024 #include <rtm/idl/RTCSkel.h>
00025 #include <rtm/idl/OpenRTMSkel.h>
00026 #include <rtm/Manager.h>
00027 #include <rtm/StateMachine.h>
00028 #include <rtm/ExecutionContextBase.h>
00029
00030
00031 #include <ace/Task.h>
00032 #include <ace/OS_NS_unistd.h>
00033 #include <vector>
00034 #include <iostream>
00035
00036 namespace RTC
00037 {
00058 class PeriodicExecutionContext
00059 : public virtual ExecutionContextBase,
00060 public ACE_Task<ACE_MT_SYNCH>
00061 {
00062 public:
00082 PeriodicExecutionContext();
00083
00105 PeriodicExecutionContext(DataFlowComponent_ptr owner,
00106 double rate = 1000.0);
00107
00121 virtual ~PeriodicExecutionContext();
00122
00142 ExecutionContextService_ptr getRef() {return m_ref;}
00143
00168 virtual int open(void *args);
00169
00189 virtual int svc(void);
00190
00217 virtual int close(unsigned long flags);
00218
00219
00220
00221
00246 virtual CORBA::Boolean is_running()
00247 throw (CORBA::SystemException);
00248
00277 virtual ReturnCode_t start()
00278 throw (CORBA::SystemException);
00279
00307 virtual ReturnCode_t stop()
00308 throw (CORBA::SystemException);
00309
00329 virtual CORBA::Double get_rate()
00330 throw (CORBA::SystemException);
00331
00361 virtual ReturnCode_t set_rate(CORBA::Double rate)
00362 throw (CORBA::SystemException);
00363
00398 virtual ReturnCode_t activate_component(LightweightRTObject_ptr comp)
00399 throw (CORBA::SystemException);
00400
00434 virtual ReturnCode_t deactivate_component(LightweightRTObject_ptr comp)
00435 throw (CORBA::SystemException);
00436
00469 virtual ReturnCode_t reset_component(LightweightRTObject_ptr comp)
00470 throw (CORBA::SystemException);
00471
00499 virtual LifeCycleState get_component_state(LightweightRTObject_ptr comp)
00500 throw (CORBA::SystemException);
00501
00520 virtual ExecutionKind get_kind()
00521 throw (CORBA::SystemException);
00522
00555 virtual ReturnCode_t add(LightweightRTObject_ptr comp)
00556 throw (CORBA::SystemException);
00557
00588 virtual ReturnCode_t remove(LightweightRTObject_ptr comp)
00589 throw (CORBA::SystemException);
00590
00610 virtual ExecutionContextProfile* get_profile()
00611 throw (CORBA::SystemException);
00612
00613 protected:
00614
00615
00616
00617 typedef LifeCycleState ExecContextState;
00618
00619
00620
00621
00622
00623
00624
00625
00626 typedef RTC_Utils::StateHolder<ExecContextState> ECStates;
00627
00648 class DFPBase
00649 {
00650 public:
00651
00669 DFPBase(UniqueId id)
00670 : ec_id(id), m_sm(3)
00671 {
00672 m_sm.setListener(this);
00673 m_sm.setEntryAction (ACTIVE_STATE, &DFPBase::on_activated);
00674 m_sm.setDoAction (ACTIVE_STATE, &DFPBase::on_execute);
00675 m_sm.setPostDoAction(ACTIVE_STATE, &DFPBase::on_state_update);
00676 m_sm.setExitAction (ACTIVE_STATE, &DFPBase::on_deactivated);
00677 m_sm.setEntryAction (ERROR_STATE, &DFPBase::on_aborting);
00678 m_sm.setDoAction (ERROR_STATE, &DFPBase::on_error);
00679 m_sm.setExitAction (ERROR_STATE, &DFPBase::on_reset);
00680
00681 ECStates st;
00682 st.prev = INACTIVE_STATE;
00683 st.curr = INACTIVE_STATE;
00684 st.next = INACTIVE_STATE;
00685 m_sm.setStartState(st);
00686 m_sm.goTo(INACTIVE_STATE);
00687 }
00688
00702 virtual ~DFPBase(){}
00703
00720 virtual void on_startup() = 0;
00721
00738 virtual void on_shutdown() = 0;
00739
00761 virtual void on_activated(const ECStates& st) = 0;
00762
00784 virtual void on_deactivated(const ECStates& st) = 0;
00785
00807 virtual void on_aborting(const ECStates& st) = 0;
00808
00834 virtual void on_error(const ECStates& st) = 0;
00835
00861 virtual void on_reset(const ECStates& st) = 0;
00862
00889 virtual void on_execute(const ECStates& st) = 0;
00890
00917 virtual void on_state_update(const ECStates& st) = 0;
00918
00936 virtual void on_rate_changed() = 0;
00937
00956 virtual void worker() {return m_sm.worker();}
00957
00975 virtual ExecContextState get_state(){ return m_sm.getState();}
00976
00984 UniqueId ec_id;
00985
00993 RTC_Utils::StateMachine<ExecContextState, DFPBase> m_sm;
00994 };
00995
00996
00997
00998
01024 template <class Object>
01025 class DFP
01026 : public DFPBase
01027 {
01028 public:
01048 DFP(Object obj, UniqueId id)
01049 : DFPBase(id), m_obj(obj), m_active(true)
01050 {
01051 }
01052
01068 void on_startup()
01069 {
01070 m_obj->on_startup(ec_id);
01071 }
01072
01088 void on_shutdown()
01089 {
01090 m_obj->on_shutdown(ec_id);
01091 }
01092
01115 void on_activated(const ECStates& st)
01116 {
01117 if (m_obj->on_activated(ec_id) != RTC::RTC_OK)
01118 {
01119 m_sm.goTo(ERROR_STATE);
01120 return;
01121 }
01122 return;
01123 }
01124
01145 void on_deactivated(const ECStates& st)
01146 {
01147 m_obj->on_deactivated(ec_id);
01148 }
01149
01169 void on_aborting(const ECStates& st)
01170 {
01171 m_obj->on_aborting(ec_id);
01172 }
01173
01193 void on_error(const ECStates& st)
01194 {
01195 m_obj->on_error(ec_id);
01196 }
01197
01217 void on_reset(const ECStates& st)
01218 {
01219 if (m_obj->on_reset(ec_id) != RTC::RTC_OK)
01220 {
01221 m_sm.goTo(ERROR_STATE);
01222 return;
01223 }
01224 return;
01225 }
01226
01252 void on_execute(const ECStates& st)
01253 {
01254 if (m_obj->on_execute(ec_id) != RTC::RTC_OK)
01255 {
01256 m_sm.goTo(ERROR_STATE);
01257 return;
01258 }
01259 return;
01260 }
01261
01287 void on_state_update(const ECStates& st)
01288 {
01289 if (m_obj->on_state_update(ec_id) != RTC::RTC_OK)
01290 {
01291 m_sm.goTo(ERROR_STATE);
01292 return;
01293 }
01294 return;
01295 }
01296
01313 void on_rate_changed()
01314 {
01315 m_obj->on_rate_changed(ec_id);
01316 }
01317
01325 Object m_obj;
01326
01334 bool m_active;
01335 };
01336
01344 struct Comp
01345 {
01346 Comp(LightweightRTObject_ptr ref, DataFlowComponent_ptr dfp,
01347 UniqueId id)
01348 : _ref(ref), _sm(dfp, id)
01349 {
01350 }
01351 Comp(const Comp& comp)
01352 : _ref(comp._ref), _sm(comp._sm.m_obj, comp._sm.ec_id)
01353 {
01354 }
01355 Comp& operator=(const Comp& comp)
01356 {
01357 _ref = comp._ref;
01358 _sm.m_obj = comp._sm.m_obj;
01359 _sm.ec_id = comp._sm.ec_id;
01360 return *this;
01361 }
01362 LightweightRTObject_var _ref;
01363 DFP<DataFlowComponent_var> _sm;
01364 };
01365
01373 struct find_comp
01374 {
01375 LightweightRTObject_var m_comp;
01376 find_comp(LightweightRTObject_ptr comp) : m_comp(comp) {}
01377 bool operator()(Comp& comp)
01378 {
01379 return comp._ref->_is_equivalent(m_comp);
01380 }
01381 };
01382
01390 struct invoke_on_startup
01391 {
01392 void operator()(Comp& comp)
01393 {
01394 comp._sm.on_startup();
01395 }
01396 };
01397
01405 struct invoke_on_shutdown
01406 {
01407 void operator()(Comp& comp)
01408 {
01409 comp._sm.on_shutdown();
01410 }
01411 };
01412
01420 struct invoke_on_rate_changed
01421 {
01422 void operator()(Comp& comp)
01423 {
01424 comp._sm.on_rate_changed();
01425 }
01426 };
01427
01435 struct invoke_worker
01436 {
01437 void operator()(Comp& comp)
01438 {
01439 comp._sm.worker();
01440 }
01441 };
01442
01450 std::vector<Comp> m_comps;
01451 typedef std::vector<Comp>::iterator CompItr;
01452
01462 bool m_state;
01463
01471 bool m_running;
01472
01480 ExecutionContextProfile m_profile;
01481
01489 long int m_usec;
01490
01498 ExecutionContextService_var m_ref;
01499
01508 bool m_nowait;
01509 };
01510 };
01511
01512 extern "C"
01513 {
01514 void PeriodicExecutionContextInit(RTC::Manager* manager);
01515 };
01516
01517 #endif