eeros_architecture:sequencer:usage
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| eeros_architecture:sequencer:usage [2015/10/27 16:53] – [Sequencer] graf | eeros_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(); | ||
| - | Sequence mySequence(" | ||
| - | | ||
| - | mainSequencer.start(& | ||
| - | mainSequencer.join(); | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | Each sequencer runs in its own thread of execution. It therefore can be in exactly one of the following states: // | ||
| - | The next step is to install a meaningfull sequence (see below [[eeros_architecture: | ||
| - | |||
| - | If it is necessary to keep data which is specific to a certain sequencer you may define your own class // | ||
| - | |||
| - | <code cpp> | ||
| - | class MySequencer : public eeros:: | ||
| - | </ | ||
| - | |||
| - | ===== Sequence ===== | ||
| - | A sequence is a well defined course of steps. These steps have to be defined by the user in its //run// method. | ||
| - | A user has to derive a class // | ||
| - | <code cpp> | ||
| - | class MySequence : public eeros:: | ||
| - | </ | ||
| - | |||
| - | As a next step you have to create an instance of // | ||
| - | <code cpp> | ||
| - | MySequence mySequence(" | ||
| - | </ | ||
| - | |||
| - | The sequencer will then run through the sequence as follows: | ||
| - | |||
| - | <code cpp> | ||
| - | init(); | ||
| - | yield(); | ||
| - | | ||
| - | if(!checkPreCondition()) | ||
| - | return SequenceResult< | ||
| - | yield(); | ||
| - | | ||
| - | run(); | ||
| - | yield(); | ||
| - | |||
| - | if(!checkPostCondition()) | ||
| - | return SequenceResult< | ||
| - | yield(); | ||
| - | |||
| - | exit(); | ||
| - | return SequenceResult< | ||
| - | </ | ||
| - | |||
| - | Every sequence starts with an //init// function. You have to implement this function in your derived class. As a next step you can check for preconditions for this sequence to be met. If the test fails the sequence will immediately stop. Here again, make sure to implement your own check function. \\ | ||
| - | The main work of the sequence is done in the function //run()//. At the end every sequence checks for possible post condition violations and runs its //exit()// function. Let's look at a simple example. | ||
| - | |||
| - | |||
| - | <code cpp> | ||
| - | class MySequence : public Sequence<> | ||
| - | public: | ||
| - | MySequence(std:: | ||
| - | |||
| - | void init() { | ||
| - | log.trace() << " | ||
| - | sleep(1); | ||
| - | } | ||
| - | |||
| - | bool checkPreCondition() { | ||
| - | log.trace() << " | ||
| - | if(robot.getPosZ() < 10) return true; | ||
| - | return false; | ||
| - | } | ||
| - | |||
| - | void run() { | ||
| - | robot.moveXY(10, | ||
| - | yield(); | ||
| - | robot.moveXY(-10, | ||
| - | } | ||
| - | |||
| - | bool checkPostCondition() { | ||
| - | log.trace() << " | ||
| - | if(robot.getPosX() < 0) return true; | ||
| - | return false; | ||
| - | } | ||
| - | |||
| - | void exit() { | ||
| - | log.trace() << " | ||
| - | sleep(1); | ||
| - | } | ||
| - | |||
| - | private: Robot& robot; | ||
| - | }; | ||
| - | </ | ||
| - | |||
| - | |||
| - | {{ sequenceruml.png? | ||
| - | |||
| - | ===== 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 // | ||
| - | |||
| - | <code c> | ||
| - | MyBlockingSubSequence* subSequence = dynamic_cast< | ||
| - | if(!subSequence){ | ||
| - | // | ||
| - | subSequence = new MyBlockingSubSequence(" | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | **Note:** | ||
| - | *In the above lines only one object of // | ||
| - | *It is not allowed to call the // | ||
| - | |||
| - | To start the sub-sequence just call //run()//, which calls all methods in the callback list (filled by // | ||
| - | |||
| - | <code c> | ||
| - | //Here we wait for the returning of the subSequence.run() method | ||
| - | while(subSequence-> | ||
| - | subSequence-> | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | ====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, | ||
| - | |||
| - | 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(" | ||
| - | </ | ||
| - | |||
| - | Here you can reuse an existing sub-sequence if you want. | ||
| - | <code c> | ||
| - | MyNonBlockingSubSequence* subSequence = dynamic_cast< | ||
| - | if(!subSequence){ | ||
| - | subSequence = new MyNonBlockingSubSequence(" | ||
| - | } | ||
| - | </ | ||
| - | |||
| - | **Note:** | ||
| - | *The constructor of the // | ||
| - | *Do not forget to call // | ||
| - | |||
| - | As soon as you have created the sub-sequence, | ||
| - | |||
| - | <code c> | ||
| - | subSequencer-> | ||
| - | </ | ||
| - | |||
| - | In an other step of the superior sequence you can wait until the non-blocking sequence is terminated by using the method: // | ||
| - | <code c> | ||
| - | //Here we wait for the subsequencer Thread | ||
| - | eeros:: | ||
| - | if(seq && seq-> | ||
| - | ExecutorService:: | ||
| - | } | ||
| - | </ | ||
eeros_architecture/sequencer/usage.1445961214.txt.gz · Last modified: 2015/10/27 16:53 by graf