User Tools

Site Tools


eeros_architecture:sequencer:define_sequence

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:define_sequence [2019/03/14 10:27] – [Waiting in Sequences or Steps] grafeeros_architecture:sequencer:define_sequence [2023/02/26 00:25] (current) – [Add Parameters] ursgraf
Line 7: Line 7:
 class MyStep : public Step { class MyStep : public Step {
 public: public:
-  MyStep(std::string name, Sequencer& seq, BaseSequence* caller) : Step(name, seq, caller) {...}+  MyStep(std::string name, Sequence* caller) : Step(name, caller) {...}
   ...   ...
 }; };
Line 13: Line 13:
 class MySequence : public Sequence { class MySequence : public Sequence {
 public: public:
-  MySequence(std::string name, Sequencer& seq, BaseSequence* caller) : Sequence(name, seq, caller, false) {...}+  MySequence(std::string name, Sequence* caller) : Sequence(name, caller, false) {...}
   ...   ...
 }; };
 </code> </code>
-Your constructor usually includes a name for the sequence or step, a reference to the sequencer, and a reference to the caller of this object. The latter point is very important, because every step or sequence must know its caller or owner. \\ +Your constructor usually includes a name for the sequence or step, a reference to the caller of this object. The latter point is very important, because every step or sequence must know its caller or owner. \\ 
-You then initialize the sequence in the initializer list by writing ''Sequence(name, seq, caller, false)''. The last parameter defines whether your sequence is blocking or nonblocking. Setting to blocking (''true'') makes this sequence block its calling sequence, setting to blocking (''false'') starts a new thread which runs the sequence in parallel to its calling sequence. A step is always blocking. +You then initialize the sequence in the initializer list by writing ''Sequence(name, caller, false)''. The last parameter defines whether your sequence is blocking or nonblocking. Setting to blocking (''true'') makes this sequence block its calling sequence, setting to blocking (''false'') starts a new thread which runs the sequence in parallel to its calling sequence. A step is always blocking. 
  
 In the body of your constructor you define the attributes of your sequence. This includes: In the body of your constructor you define the attributes of your sequence. This includes:
Line 28: Line 28:
 class MySequence : public Sequence { class MySequence : public Sequence {
 public: public:
-  MySequence(std::string name, Sequencer& seq, BaseSequence* caller) : Sequence(name, seq, caller, false) {+  MySequence(std::string name, Sequence* caller) : Sequence(name, caller, false) {
     // this sequence will run in its own thread and concurrently to its caller     // this sequence will run in its own thread and concurrently to its caller
     setTimeoutTime(2.5);                          // the built-in timeout monitor has its timeout condition set to 2.5s     setTimeoutTime(2.5);                          // the built-in timeout monitor has its timeout condition set to 2.5s
Line 37: Line 37:
 </code> </code>
  
-If you define a main sequence which has no calling sequence and which must be nonblocking per default, you can make use of a simpler constructor by calling+If you define a main sequence which has no calling sequence and which must be nonblocking per default, you can make use of another constructor by calling
 <code cpp> <code cpp>
 class MainSequence : public Sequence { class MainSequence : public Sequence {
Line 53: Line 53:
     step2();     step2();
     step3();     step3();
 +    return 0;
   }   }
 </code> </code>
-Its mandatory to implement this function. If not, no work is done and the step or sequence terminates immediately. \\+Its mandatory to implement this function. If not, no work is done and the step or sequence terminates immediately.  
 +A step or blocking sequence can return a value of type ''int''. This can be useful to hand back basic information to the calling sequence.  \\ 
 There might be sequences which should never stop. This must be done as shown below: There might be sequences which should never stop. This must be done as shown below:
 <code cpp> <code cpp>
 public: public:
   int action() {   int action() {
-    while (Sequencer::running) step1();+    while (state == SequenceState::running) step1();
     // while (true) step1();  // WRONG!     // while (true) step1();  // WRONG!
 +    return 0;
   }   }
 </code> </code>
-This guarantees that the sequence could be stopped by the main program due to some external event such as a signal.+This guarantees that the sequence could be aborted, resumed or restarted due to exception sequences.
 ===== Define Preconditions ===== ===== Define Preconditions =====
 You may want to start a sequence or step only if a certain precondition is met. Override the function //checkPreCondition()//, e.g.: You may want to start a sequence or step only if a certain precondition is met. Override the function //checkPreCondition()//, e.g.:
Line 83: Line 87:
 <code cpp> <code cpp>
   int operator() (double x, double y) {   int operator() (double x, double y) {
-    this.x = x; // store the first parameter into a local variable for further use +    this->x = x; // store the first parameter into a local variable for further use 
-    this.y = y; // store the second parameter into a local variable for further use +    this->y = y; // store the second parameter into a local variable for further use 
     return start();  // this will start the step or sequence     return start();  // this will start the step or sequence
   }   }
Line 109: Line 113:
  
 ===== Waiting in Sequences or Steps ===== ===== Waiting in Sequences or Steps =====
-As mentioned before you should never wait by using //sleep// in a action method. However, quite often it is desirable to wait for some time to pass when running sequences. How to do properly? Study the following example: +As mentioned before you should never wait by using //sleep// in a action method. However, quite often it is desirable to wait for some time to pass when running sequences. How to do properly? Use the predefined step ''Wait''Study the examples in [[getting_started:tutorials:start|]]Contrary to a simple //sleep// it does not block the sequencer and the checking of monitors of this step or sequence continues unhindered.
-<code cpp> +
-class StepA : public Step { +
-public: +
-  StepA(std::string name, Sequencer& seq, BaseSequence* caller) : Step(name, seq, caller) { } +
-  int action() {time = std::chrono::steady_clock::now();+
-  bool checkExitCondition() { +
-    return ((std::chrono::duration<double>)(std::chrono::steady_clock::now() - time)).count() > 3.2; +
-  } +
-private: +
-  std::chrono::time_point<std::chrono::steady_clock> time; +
-}; +
-</code> +
-This step simply takes a time stamp when running its action method. Its exit condition becomes ''true'' as soon as a waiting time of 3.2s has elapsedHowever, contrary to a simple //sleep// it does not block the sequencer and the checking of monitors of this step or sequence continues unhindered.+
  
-===== Returning Values ===== 
  
eeros_architecture/sequencer/define_sequence.1552555659.txt.gz · Last modified: 2019/03/14 10:27 by graf