User Tools

Site Tools


eeros_architecture:sequencer:usage

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
eeros_architecture:sequencer:usage [2015/10/27 11:40] – [Sequencer] grafeeros_architecture:sequencer:usage [2015/10/30 10:48] (current) – removed graf
Line 1: Line 1:
-======Sequencer Usage====== 
-This page describes the usage of the sequencer in the EEROS framework.  
  
-===== Sequencer ===== 
-Create an instance of the sequencer. If its the first sequencer you define, it will automatically be the main sequencer. 
-<code cpp> 
-int main() { 
-  Sequencer mainSequencer();  // define sequencer 
-  Sequence mySequence("My Sequence", &mainSequencer); // define sequence 
-   
-  mainSequencer.start(&mySequence);  // start the sequencer 
-  mainSequencer.join();  // wait for the sequencer to finish 
-} 
-</code> 
- 
-Each sequencer runs in its own thread of execution. It therefore can be in exactly one of the following states: //executing, waiting, terminating, terminated, idle//. Further, a sequencer runs either in //automatic// mode or it can be in //stepping// mode. Upon creation the thread runs and the state of the sequencer is //idle//. \\ 
-The next step is to install a meaningfull sequence (see below [[eeros_architecture:sequencer:usage#sequence|Sequence]]). After this you can start the sequencer with //start()//. This sets its state to //executing//. The main program may terminate when the main sequencer has terminated. For this purpose it has to wait for the sequencer thread with //join()// 
- 
-If it is necessary to keep data which is specific to a certain sequencer you may define your own class //**MySequencer**// as an extension of //**Sequencer**// and define the data therein.  
- 
-<code cpp> 
-  class MySequencer : public eeros::sequencer::Sequencer 
-</code> 
- 
-===== Sequence ===== 
-A sequence is a series of steps. The order has to be defined by the user. A step corresponds to a single method, such as  
- 
-<code c> 
-  void init(); 
-  void homed(); 
-  void move(); 
-</code> 
- 
-Implement each of the methods according to its task. Then, derive //**MySequence**// from  //**Sequence**//: 
-<code c> 
-  class MySequence : public eeros::sequencer::Sequence 
-</code> 
- 
-As a next step you have to create an instance of //MySequence//. By doing so you can choose a name an assign this sequence to a sequencer. 
-<code c> 
-  MySequence sequence("MySequence", mainSequencer); // define sequence 
-</code> 
-Add the steps to the sequence with the method //fillCallBacks()//. This method is a purely virtual method, meaning that the user has to implement it in the derived class //MySequence//. 
-Insert these methods in the list of callbacks in your implementation of the method //fillCallBacks()//. 
-<code c> 
-void MySequence::fillCallBacks(){ 
-  addCallBack(static_cast<eeros::sequencer::Sequence::method>(&MySequence::init)); 
-  addCallBack(static_cast<eeros::sequencer::Sequence::method>(&MySequence::homed)); 
-  addCallBack(static_cast<eeros::sequencer::Sequence::method>(&MySequence::move)); 
-} 
-</code> 
- 
-The constructor of //MySequence// should call //addRunnable()// of the member reference //callerThread//. This adds the Sequencer which handles //MySequence// to the list of runnables. All sequence objects are saved in a list, so you can reuse them. Since the sequences are identified by name, the name has to be unique, or else you will get an exception. 
- 
-<code c> 
-/** constructor MySequence 
-* name: Name of the Sequence 
-* caller: Sequencer to which this sequences belongs 
-*/ 
-MySequence::MySequence(std::string name, eeros::sequencer::Sequencer& caller) 
- : eeros::sequencer::Sequence(name, caller) { 
-  callerThread.addRunnable(this); 
-} 
-</code> 
- 
-Do not forget to stop the sequencer by calling //stop()// of the class //Sequencer//. 
-<code c> 
-  callerThread.stop(); 
-</code> 
- 
-{{ sequenceruml.png?350 | //Class diagramm with Sequencer and Sequence//}} 
- 
-===== Subsequence===== 
-A subsequence is a sequence which is called by a step of another sequence. Such a subsequence can be called in a blocking or non-blocking way. Blocking means that the step waits (or blocks) until the subsequence has finished. Non-blocking means that subsequence and main sequence run concurrently.  
- 
-====Blocking Call of a Subsequence==== 
-If you want to save your own data in the sequence, you need to create a new instance of a sequence. This should be done in the desired step (method) of the superior sequence.  
-e.g. in the method //MoveBlocking()// 
- 
-<code c> 
-MyBlockingSubSequence* subSequence = dynamic_cast<MyBlockingSubSequence*>eeros::sequencer::Sequence::getSequence("BlockingSubSequence")); 
-if(!subSequence){ 
-  //callerThread for Blocking Sub Sequence is the same as is in this running Sequence. 
-  subSequence = new MyBlockingSubSequence("BlockingSubSequence", callerThread); 
-} 
-</code> 
- 
-**Note:** 
-  *In the above lines only one object of //MyBlockingSubSequence// with the name //BlockingSubSequence// is created. 
-  *It is not allowed to call the //callerThread.addRunnable(this)// method, because the superior sequence calls the blocking sub-sequence directly by the //run()// method. 
- 
-To start the sub-sequence just call //run()//, which calls all methods in the callback list (filled by //fillCallBacks()//). Be sure that the sub-sequence is terminated before you restart it. This could happen, for example, in an exception handling ( [[.:..:sequencer_usage:error_handler | Error Handler]] ). 
- 
-<code c> 
-//Here we wait for the returning of the subSequence.run() method 
-while(subSequence->getState() != eeros::sequencer::kSequenceFinished){ 
- subSequence->run(); 
-} 
-</code> 
- 
-====Non Blocking Call of a Sub-Sequence==== 
-Remark: Please use pointer for a non blocking call, because the memory referenced by a pointer to an object exists until you delete it However, an object is removed as soon the scope of the method is no longer being used. In the case where both sequences (sequence and sub-sequence) run contemporaneously, the sub-sequence should not be deleted at the end of the step (method). That's why you should use pointers! 
- 
-A non-blocking sub-sequence has to be created as a thread, so you need a sub-sequencer for starting the new thread. 
-e.g.: 
-<code c> 
-MySequencer* subSequencer = new MySequencer("SubSequencer"); 
-</code> 
- 
-Here you can reuse an existing sub-sequence if you want. 
-<code c> 
-MyNonBlockingSubSequence* subSequence = dynamic_cast<MyNonBlockingSubSequence*>(eeros::sequencer::Sequence::getSequence("NonBlockingSubSequence")); 
-if(!subSequence){ 
-  subSequence = new MyNonBlockingSubSequence("NonBlockingSubSequence",subSequencer); 
-} 
-</code> 
- 
-**Note:** 
-  *The constructor of the //MyNonBlockingSequence// class has to call //callerThread.addRunnable(this)// to add itself to the sub-sequencer runnable list, or else the callback methods are not called by the sub-sequencer. 
-  *Do not forget to call //callerThread.stop()// in the last step of the sub-sequence. 
- 
-As soon as you have created the sub-sequence, you can start the sub-sequencer, which creates the threads to run all steps. 
- 
-<code c> 
-  subSequencer->start(); 
-</code> 
- 
-In an other step of the superior sequence you can wait until the non-blocking sequence is terminated by using the method: //ExecutorService::waitForSequenceEnd(…);//. 
-<code c> 
-//Here we wait for the subsequencer Thread 
-eeros::sequencer::Sequencer* seq = eeros::sequencer::Sequencer::getMainSequencer()->findSequencer("SubSequencer"); 
-if(seq && seq->getStatus() != kStopped){ 
-  ExecutorService::waitForSequenceEnd(seq); 
-} 
-</code> 
eeros_architecture/sequencer/usage.1445942455.txt.gz · Last modified: 2015/10/27 11:40 (external edit)