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