User Tools

Site Tools


eeros_architecture:sequencer:subsequence

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:subsequence [2015/10/29 21:32] – [Simple Example] grafeeros_architecture:sequencer:subsequence [2015/10/31 09:05] (current) – external edit 127.0.0.1
Line 3: Line 3:
  
 =====Blocking Call of a Subsequence===== =====Blocking Call of a Subsequence=====
-If you want to save your own data in the sequence, you need to create new instance of a sequence. This should be done in the desired step (method) of the superior sequence.  +If several steps of a sequence have to be repeated more than onceit might be worth to pack them into separate subsequence. This subsequence offers all the features of any sequence such as init or exit functions as well as checking of pre and post conditionsHowever, a blocking call to a subsequence allows to use the same sequencer as the calling sequence.
-e.g. in the method //MoveBlocking()//+
  
 ===== Simple Example ===== ===== Simple Example =====
  
-We first define a class for the sub- or secondary sequence as follows:+We continue with our hypothetical robot from the example in [[eeros_architecture:sequencer:sequence|]]. We first define a class for the sub- or secondary sequence as follows:
 <code cpp> <code cpp>
 class SequenceB : public Sequence<void,double> { class SequenceB : public Sequence<void,double> {
 public: public:
-  SequenceA(std::string name, Sequencer* seq, Robot& r) : Sequence<void,double>(name, seq), robot(r){ }+  SequenceB(std::string name, Sequencer* seq, Robot& r) : Sequence<void,double>(name, seq), robot(r){ }
   
   void run(double z) {   void run(double z) {
-    robot.moveXY(z);+    robot.moveZ(z);
     yield();     yield();
-    robot.moveXY(0);+    robot.moveZ(0);
   }   }
   
Line 36: Line 35:
   void run() {   void run() {
     robot.moveXY(10, -20);     robot.moveXY(10, -20);
-    seqB(5); +    sequenceB(5); 
-    robot.moveXY(-10, -30); +    robot.moveXY(-10, 30); 
-    seqB(5);+    sequenceB(5);
     robot.moveXY(0, 0);     robot.moveXY(0, 0);
   }   }
Line 44: Line 43:
 private:  private: 
   Robot& robot;   Robot& robot;
-  SequenceB seqB;+  SequenceB sequenceB;
 }; };
 </code> </code>
-In our main program we declare a sequencer for the main sequence. The same sequencer will also handle the subsequence. Sequence A and B do not run concurrently. The following figure shows the flow of action+In our main program we declare a sequencer for the main sequence. The same sequencer will also handle the subsequence. Sequence A and B do not run concurrently.  
-====Non Blocking Call of a Sub-Sequence==== +<code cpp> 
-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-sequencerun contemporaneously, the sub-sequence should not be deleted at the end of the step (method). That's why you should use pointers! +int main() { 
- +  Sequencer sequencer; 
-non-blocking sub-sequence has to be created as a threadso you need a sub-sequencer for starting the new thread+  SequenceA seqA("Seq A"&sequencer, robot); 
-e.g.: +  sequencerA.start(&seqA); 
-<code c> +  sequencerA.join()
-MySequencer* subSequencer = new MySequencer("SubSequencer");+};
 </code> </code>
 +The following figure shows the flow of action.
 +{{ :eeros_architecture:sequencer:subsequenceblocking.png?400 |}}
 +===== Nonblocking Call of a Subsequence =====
  
-Here you can reuse an existing sub-sequence if you want. +A nonblocking subsequence has to run in its own thread. For this reason you need a separate subsequencer for it. Both sequences can now run concurrently. A certain step in a sequence could depend on a subsequence to have finished. For this purpose the function //join()// will wait for the subsequence to finish. 
-<code c+ 
-MyNonBlockingSubSequence* subSequence = dynamic_cast<MyNonBlockingSubSequence*>(eeros::sequencer::Sequence::getSequence("NonBlockingSubSequence")); +==== Simple Example ==== 
-if(!subSequence){ + 
-  subSequence = new MyNonBlockingSubSequence("NonBlockingSubSequence",subSequencer); +We first define a class for the sub- or secondary sequence as follows: 
-}+<code cpp
 +class SequenceB : public Sequence<> 
 +public: 
 +  SequenceB(std::string name, Sequencer* seq, Robot& r) : Sequence<void,double>(name, seq), robot(r){ } 
 +  
 +  void run() { 
 +    robot.moveZ(5); 
 +    sleep(3); 
 +    yield(); 
 +    robot.moveZ(0); 
 +  } 
 +  
 +private:  
 +  Robot& robot; 
 +};
 </code> </code>
  
-**Note:** +The //run()// method simply moves in z direction andafter a pause, returns to the original position.
-  *The constructor of the //MyNonBlockingSequence// class has to call //callerThread.addRunnable(this)// to add itself to the sub-sequencer runnable listor 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.+We can now define our first or main sequence with 
  
-<code c+<code cpp> 
-  subSequencer->start();+class SequenceA : public Sequence<>
 +public: 
 +  SequenceA(std::string name, Sequencer* seq, Robot& r, Sequencer& seqB) : Sequence<>(name, seq), robot(r), seqB(seqB) { } 
 +  
 +  void run() { 
 +    robot.moveXY(10, -20); 
 +    sequencerB.start(0U)
 +    robot.moveXY(-10, 30); 
 +    sequencerB.join(); 
 +    robot.moveXY(0, 0); 
 +  } 
 +  
 +private:  
 +  Robot& robot; 
 +  Sequencer& sequencerB; 
 +};
 </code> </code>
- +In our main program we declare a sequencer for the main sequence. A second sequencer will run the subsequence.  
-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 cpp
-<code c+int main() { 
-//Here we wait for the subsequencer Thread +  Sequencer sequencerA, sequencerB; 
-eeros::sequencer::Sequencer* seq = eeros::sequencer::Sequencer::getMainSequencer()->findSequencer("SubSequencer"); +  SequenceB seqB("Seq B", &sequencerB, robot)
-if(seq &seq->getStatus() != kStopped){ +  SequenceA seqA("Seq A", &sequencerA, robot, sequencerB); 
-  ExecutorService::waitForSequenceEnd(seq); +  sequencerB.addCmdSequence(&seqB); 
-}+  sequencerA.start(&seqA); 
 +  sequencerA.join(); 
 +};
 </code> </code>
 +
 +In the second step of the sequence A the sequence is started in its own thread. After this both run concurrently. The forth step of sequence A then waits for the sequence B to finish.
 +The following figure shows the flow of action.
 +{{ :eeros_architecture:sequencer:subsequencenonblocking.png?400 |}}
eeros_architecture/sequencer/subsequence.1446150771.txt.gz · Last modified: 2015/10/29 21:32 (external edit)