00001
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #ifndef PeriodicExecutionContext_h
00042 #define PeriodicExecutionContext_h
00043
00044 #include <rtm/RTC.h>
00045 #include <rtm/idl/RTCSkel.h>
00046 #include <rtm/idl/OpenRTMSkel.h>
00047 #include <rtm/Manager.h>
00048 #include <rtm/StateMachine.h>
00049 #include <rtm/ExecutionContextBase.h>
00050
00051
00052 #include <ace/Task.h>
00053 #include <ace/OS_NS_unistd.h>
00054 #include <vector>
00055 #include <iostream>
00056
00057 namespace RTC
00058 {
00059
00060 class PeriodicExecutionContext
00061 : public virtual ExecutionContextBase,
00062 public ACE_Task<ACE_MT_SYNCH>
00063 {
00064 public:
00065 PeriodicExecutionContext();
00066 PeriodicExecutionContext(DataFlowComponent_ptr owner,
00067 double rate = 1000.0);
00068 virtual ~PeriodicExecutionContext();
00069
00070 ExecutionContextService_ptr getRef() {return m_ref;}
00071
00091 virtual int open(void *args);
00092
00093
00110 virtual int svc(void);
00111
00112
00131 virtual int close(unsigned long flags);
00132
00133
00134
00135
00136
00137
00138 virtual CORBA::Boolean is_running();
00139
00140 virtual ReturnCode_t start();
00141 virtual ReturnCode_t stop();
00142
00143 virtual CORBA::Double get_rate();
00144 virtual ReturnCode_t set_rate(CORBA::Double rate);
00145
00146 virtual ReturnCode_t activate_component(LightweightRTObject_ptr comp);
00147 virtual ReturnCode_t deactivate_component(LightweightRTObject_ptr comp);
00148 virtual ReturnCode_t reset_component(LightweightRTObject_ptr comp);
00149
00150 virtual LifeCycleState get_component_state(LightweightRTObject_ptr comp);
00151 virtual ExecutionKind get_kind();
00152 virtual ReturnCode_t add(LightweightRTObject_ptr comp);
00153 virtual ReturnCode_t remove(LightweightRTObject_ptr comp);
00154
00155 virtual ExecutionContextProfile* get_profile();
00156
00157
00158 protected:
00159
00160
00161
00162 typedef LifeCycleState ExecContextState;
00163
00164
00165
00166
00167
00168
00169
00170
00171 typedef StateHolder<ExecContextState> ECStates;
00172
00173 class DFPBase
00174 {
00175 public:
00176
00177 DFPBase(UniqueId id)
00178 : ec_id(id), m_sm(3)
00179 {
00180 m_sm.setListener(this);
00181 m_sm.setEntryAction (ACTIVE_STATE,
00182 &DFPBase::on_activated);
00183 m_sm.setDoAction (ACTIVE_STATE,
00184 &DFPBase::on_execute);
00185 m_sm.setPostDoAction(ACTIVE_STATE,
00186 &DFPBase::on_state_update);
00187 m_sm.setExitAction (ACTIVE_STATE,
00188 &DFPBase::on_deactivated);
00189 m_sm.setEntryAction (ERROR_STATE,
00190 &DFPBase::on_aborting);
00191 m_sm.setDoAction (ERROR_STATE,
00192 &DFPBase::on_error);
00193 m_sm.setExitAction (ERROR_STATE,
00194 &DFPBase::on_reset);
00195
00196 ECStates st;
00197 st.prev = INACTIVE_STATE;
00198 st.curr = INACTIVE_STATE;
00199 st.next = INACTIVE_STATE;
00200 m_sm.setStartState(st);
00201 m_sm.goTo(INACTIVE_STATE);
00202 }
00203 virtual ~DFPBase(){}
00204 virtual ReturnCode_t on_startup() = 0;
00205 virtual ReturnCode_t on_shutdown() = 0;
00206
00207 virtual ReturnCode_t on_activated(const ECStates& st) = 0;
00208 virtual ReturnCode_t on_deactivated(const ECStates& st) = 0;
00209 virtual ReturnCode_t on_aborting(const ECStates& st) = 0;
00210 virtual ReturnCode_t on_error(const ECStates& st) = 0;
00211 virtual ReturnCode_t on_reset(const ECStates& st) = 0;
00212 virtual ReturnCode_t on_execute(const ECStates& st) = 0;
00213 virtual ReturnCode_t on_state_update(const ECStates& st) = 0;
00214
00215 virtual ReturnCode_t on_rate_changed() = 0;
00216 virtual ReturnCode_t worker() {return m_sm.worker();}
00217 virtual ExecContextState get_state(){ return m_sm.getState();}
00218 UniqueId ec_id;
00219 StateMachine<ExecContextState, ReturnCode_t, DFPBase> m_sm;
00220 };
00221
00222
00223
00224
00225
00226 template <class Object>
00227 class DFP
00228 : public DFPBase
00229 {
00230 public:
00231 DFP(Object obj, UniqueId id)
00232 : DFPBase(id), m_obj(obj), m_active(true)
00233 {
00234
00235 }
00236 ReturnCode_t on_startup()
00237 {
00238 return m_obj->on_startup(ec_id);
00239 }
00240 ReturnCode_t on_shutdown()
00241 {
00242 return m_obj->on_shutdown(ec_id);
00243 }
00244
00245 ReturnCode_t on_activated(const ECStates& st)
00246 {
00247 if (m_obj->on_activated(ec_id) != RTC::RTC_OK)
00248 {
00249 m_sm.goTo(ERROR_STATE);
00250 return RTC::RTC_ERROR;
00251 }
00252 return RTC::RTC_OK;
00253 }
00254 ReturnCode_t on_deactivated(const ECStates& st)
00255 {
00256 if (m_obj->on_deactivated(ec_id) != RTC::RTC_OK)
00257 {
00258 m_sm.goTo(ERROR_STATE);
00259 return RTC::RTC_ERROR;
00260 }
00261 return RTC::RTC_OK;
00262 }
00263
00264 ReturnCode_t on_aborting(const ECStates& st)
00265 {
00266 return m_obj->on_aborting(ec_id);
00267 }
00268
00269 ReturnCode_t on_error(const ECStates& st)
00270 {
00271 return m_obj->on_error(ec_id);
00272 }
00273
00274 ReturnCode_t on_reset(const ECStates& st)
00275 {
00276 if (m_obj->on_reset(ec_id) != RTC::RTC_OK)
00277 {
00278 m_sm.goTo(ERROR_STATE);
00279 return RTC::RTC_ERROR;
00280 }
00281 return RTC::RTC_OK;
00282 }
00283
00284 ReturnCode_t on_execute(const ECStates& st)
00285 {
00286 if (m_obj->on_execute(ec_id) != RTC::RTC_OK)
00287 {
00288 m_sm.goTo(ERROR_STATE);
00289 return RTC::RTC_ERROR;
00290 }
00291 return RTC::RTC_OK;
00292 }
00293
00294 ReturnCode_t on_state_update(const ECStates& st)
00295 {
00296 if (m_obj->on_state_update(ec_id) != RTC::RTC_OK)
00297 {
00298 m_sm.goTo(ERROR_STATE);
00299 return RTC::RTC_ERROR;
00300 }
00301 return RTC::RTC_OK;
00302 }
00303
00304 ReturnCode_t on_rate_changed()
00305 {
00306 return m_obj->on_rate_changed(ec_id);
00307 }
00308
00309 Object m_obj;
00310 bool m_active;
00311 };
00312
00313 struct Comp
00314 {
00315 Comp(LightweightRTObject_ptr ref, DataFlowComponent_ptr dfp,
00316 UniqueId id)
00317 : _ref(ref), _sm(dfp, id)
00318 {
00319 }
00320 Comp(const Comp& comp)
00321 : _ref(comp._ref), _sm(comp._sm.m_obj, comp._sm.ec_id)
00322 {
00323 }
00324 Comp& operator=(const Comp& comp)
00325 {
00326 _ref = comp._ref;
00327 _sm.m_obj = comp._sm.m_obj;
00328 _sm.ec_id = comp._sm.ec_id;
00329 return *this;
00330 }
00331 LightweightRTObject_var _ref;
00332 DFP<DataFlowComponent_var> _sm;
00333 };
00334
00335
00336
00337 struct find_comp
00338 {
00339 LightweightRTObject_var m_comp;
00340 find_comp(LightweightRTObject_ptr comp) : m_comp(comp) {}
00341 bool operator()(Comp& comp)
00342 {
00343 return comp._ref->_is_equivalent(m_comp);
00344 }
00345 };
00346
00347
00348 struct invoke_on_startup
00349 {
00350 void operator()(Comp& comp)
00351 {
00352 comp._sm.on_startup();
00353 }
00354 };
00355
00356 struct invoke_on_shutdown
00357 {
00358 void operator()(Comp& comp)
00359 {
00360 comp._sm.on_shutdown();
00361 }
00362 };
00363
00364 struct invoke_on_rate_changed
00365 {
00366 void operator()(Comp& comp)
00367 {
00368 comp._sm.on_rate_changed();
00369 }
00370 };
00371
00372 struct invoke_worker
00373 {
00374 void operator()(Comp& comp)
00375 {
00376 comp._sm.worker();
00377 }
00378 };
00379
00380 std::vector<Comp> m_comps;
00381 typedef std::vector<Comp>::iterator CompItr;
00382 bool m_running;
00383 ExecutionContextProfile m_profile;
00384 long int m_usec;
00385 ExecutionContextService_var m_ref;
00386
00387
00388 };
00389 };
00390
00391 extern "C"
00392 {
00393 void PeriodicExecutionContextInit(RTC::Manager* manager);
00394 };
00395
00396 #endif