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