Hello Pipeline!#
The examples presented on this page try to be as simple as possible.
The resulting applications will not be particularly useful, but introduce a few basic concepts of the Pipeline
in a practical manner.
These examples will not involve any predictor or controller.
The examples presented on this page are snippets from the file applications/demo_hello_pipeline/main.cpp
.
Example 1 - InOutputs only#
In example 1, we create a Pipeline
object, add a few InOutput
instance and perform three periodic updates (ticks).
1void Example1(mpmca::utilities::Logger& logger)
2{
3 using namespace mpmca::pipeline;
4
5 // First, we create a Pipeline Options object, but do not modify it.
6 Pipeline::Options pipeline_options;
7 pipeline_options.mark_nondeterministic_log_output = true;
8
9 // Then, construct the pipeline.
10 Pipeline pipeline{pipeline_options};
11
12 // After construction, we can add InOutputs, Tasks and Steps. Here, we add
13 // three InOutputs, of which two are of type HelloWorld, and one is of type
14 // EmptyInOutput. The boolean option controls whether messages are printed.
15 pipeline.AddInOutput<in_output::HelloWorld>("HelloWorld InOutput One",
16 true);
17 pipeline.AddInOutput<in_output::HelloWorld>("HelloWorld InOutput Two",
18 true);
19 pipeline.AddInOutput<in_output::EmptyInOutput>("EmptyInOuput");
20
21 // After constructing all InOutputs, Tasks and Steps, and before running,
22 // the pipeline needs to be "prepared". In the preparing stage, the
23 // InOutputs and Steps may perform expensive (blocking) operations that
24 // could not be done during construction, and take too long to be done while
25 // the pipeline is being "ticked" periodically. The InOuputs and Steps
26 // should also declare themselves 'safe' to be ticked periodically.
27 pipeline.Prepare();
28
29 // This loop performs the periodic ticking of the pipeline.
30 for (size_t t = 0; t < 3; ++t) {
31 // This marks the start of one sample.
32 logger.Info("==== Start sample " + std::to_string(t) + " ====");
33
34 // Each sample, the pipeline needs to be "ticked". During a Tick() call,
35 // all InOutputs are "ticked".
36 pipeline.Tick();
37
38 // The Task runs at an integer multiple rate of the InOutputs. To check
39 // whether the current *Tick* is a *MainTick*, the
40 // GetCurrentTickIsMainTick() method can be called.
41 if (pipeline.GetCurrentTickIsMainTick(0)) {
42 // If this Tick is a MainTick, we need to call MainTick().
43 // The MainTick() call can be performed from a different thread than
44 // the thread from where Tick() is called.
45 pipeline.MainTick(0);
46 }
47
48 // This marks the end of the sample.
49 logger.Info("==== End sample " + std::to_string(t) + " ====");
50 }
51}
52
53// Run this example, by running ./demo_hello_pipeline --run_example1
./demo_hello_pipeline --run_example1
.
The expected output is:
1[Main <main>] : <<<<< Example 1 >>>>>
2[HelloWorld InOutput One <HelloWorld>] : Constructor
3[HelloWorld InOutput Two <HelloWorld>] : Constructor
4[HelloWorld InOutput One <HelloWorld>] : PrepareInOutputMessageBus(MessageBus&)
5[HelloWorld InOutput Two <HelloWorld>] : PrepareInOutputMessageBus(MessageBus&)
6[HelloWorld InOutput One <HelloWorld>] : CheckInOutputMessageBusPrepared(const MessageBus&)
7[HelloWorld InOutput Two <HelloWorld>] : CheckInOutputMessageBusPrepared(const MessageBus&)
8[HelloWorld InOutput One <HelloWorld>] : Prepare()
9[HelloWorld InOutput Two <HelloWorld>] : Prepare()
10[Pipeline <Pipeline>] : Prepared pipeline. Safety status is SAFE.
11[Main <main>] : ==== Start sample 0 ====
12[Pipeline <Pipeline>] : Main state changed.
13State machine state: BOOTING
14 HelloWorld InOutput One BOOTING NONE
15 HelloWorld InOutput Two BOOTING NONE
16 EmptyInOuput BOOTING NONE
17
18[HelloWorld InOutput One <HelloWorld>] : Tick()
19[HelloWorld InOutput Two <HelloWorld>] : Tick()
20[Main <main>] : ==== End sample 0 ====
21[Main <main>] : ==== Start sample 1 ====
22[Pipeline <Pipeline>] : Client state(s) changed.
23State machine state: BOOTING
24 HelloWorld InOutput One BOOTING BOOTED
25 HelloWorld InOutput Two BOOTING BOOTED
26 EmptyInOuput BOOTING BOOTED
27
28[Pipeline <Pipeline>] : Main state changed.
29State machine state: IDLE
30 HelloWorld InOutput One IDLE NONE
31 HelloWorld InOutput Two IDLE NONE
32 EmptyInOuput IDLE NONE
33
34[HelloWorld InOutput One <HelloWorld>] : Tick()
35[HelloWorld InOutput Two <HelloWorld>] : Tick()
36[Main <main>] : ==== End sample 1 ====
37[Main <main>] : ==== Start sample 2 ====
38[HelloWorld InOutput One <HelloWorld>] : Tick()
39[HelloWorld InOutput Two <HelloWorld>] : Tick()
40[Main <main>] : ==== End sample 2 ====
41[Pipeline <Pipeline>] : Time measurement results for InOutput tick calls:
42 tick:HelloWorld InOutput One [us] min:
43 tick:HelloWorld InOutput Two [us] min:
44 tick:EmptyInOuput [us] min:
45[HelloWorld InOutput One <HelloWorld>] : ~HelloWorld()
46[HelloWorld InOutput Two <HelloWorld>] : ~HelloWorld()
Observe the following:
- The two
HelloWorld
instances print debug output in their constructors,Prepare()
,Tick()
andMainTick()
functions. TheEmptyInOutput
does not. - The
Pipeline
does not contain aTask
withStep
instances, and therefor, only theTick()
functions are called. TheMainTick()
functions are not called. - At the start of the first sample, all
InOutput
instances are in theBOOTING
state. During this sample, they all report that they have completed booting (i.e., they are booted) and can advance to theIDLE
state. They declare themselvesBOOTED
. - At the start of the second sample, the
StateMachine
is still inBOOTING
, but detects that allInOutput
instances have reported themselvesBOOTED
, and therefore moves the overall state toIDLE
. TheInOutput
instances will be inIDLE
when theirTick()
function is called. - At the third sample, nothing happens to the
StateMachine
and therefor it produces no output. - When
Pipeline
object is destructed, it prints some time measurement related statistics.
Example 2 - InOutputs and Steps#
In example 2, we extend Example 1 by also adding a Task
that will contain two Step
instances. The update loop now performs 7 ticks.
1void Example2(mpmca::utilities::Logger& logger)
2{
3 using namespace mpmca;
4
5 // First, we create a Pipeline object and add two InOutputs, similar to
6 // Example1.
7 pipeline::Pipeline::Options pipeline_options;
8 pipeline_options.mark_nondeterministic_log_output = true;
9 // We explicitly set the base_step_ms option to 1, which means that the
10 // InOutput update rate is once every millisecond.
11 pipeline_options.base_step_ms = 1;
12 // We also explicitly set the command_buffer_length option to 3, which means
13 // that the MainTick() of the Task may take 3 samples longer than intended.
14 // Search the documentation for "Command Buffer" for more
15 // information.
16 pipeline_options.command_buffer_length = 3;
17
18 pipeline::Pipeline pipeline{pipeline_options};
19
20 pipeline.AddInOutput<pipeline::in_output::HelloWorld>(
21 "Hello World InOutput One", true);
22 pipeline.AddInOutput<pipeline::in_output::HelloWorld>(
23 "Hello World InOutput Two", true);
24
25 // In this example, we also add a Task, containing two Steps.
26 // The `Horizon` argument refers to the MPC horizon properties. This
27 // constructor will create a Horizon with 50 steps, where each steps has a
28 // length of 3 milliseconds.
29 auto task = pipeline.MakeTask("Task", utilities::Horizon(3, 50));
30 // The behavior of the HelloWorld step is similar to the HelloWorld
31 // InOutput.
32 task->AddStep<pipeline::step::HelloWorld>("Hello World Step One", true);
33 task->AddStep<pipeline::step::HelloWorld>("Hello World Step Two", true);
34
35 // Again, we prepare all InOutputs and Steps.
36 pipeline.Prepare();
37
38 // And run the main loop.
39 for (size_t t = 0; t < 7; ++t) {
40 if (pipeline.GetNextTickIsMainTick(0)) {
41 logger.Info(
42 "The next sample is a MainTick! Both Tick and MainTick should "
43 "be called.");
44 }
45 else {
46 logger.Info(
47 "The next sample is a Tick! Only Tick should be called.");
48 }
49
50 logger.Info("==== Start sample " + std::to_string(t) + " ====");
51 pipeline.Tick();
52
53 if (pipeline.GetCurrentTickIsMainTick(0))
54 pipeline.MainTick(0);
55
56 logger.Info("==== End sample " + std::to_string(t) + " ====");
57 }
58}
Run this example, by running ./demo_hello_pipeline --run_example2
.
The expected output is as follows:
1[Main <main>] : <<<<< Example 2 >>>>>
2[Hello World InOutput One <HelloWorld>] : Constructor
3[Hello World InOutput Two <HelloWorld>] : Constructor
4[Task <Task>] : This Task will tick once every 3 base ticks.
5[Task <Task>] : The total horizon length of this Task is 150 ms and has 50 steps.
6[Hello World Step One <HelloWorld>] : Constructor
7[Hello World Step Two <HelloWorld>] : Constructor
8[Hello World InOutput One <HelloWorld>] : PrepareInOutputMessageBus(MessageBus&)
9[Hello World InOutput Two <HelloWorld>] : PrepareInOutputMessageBus(MessageBus&)
10[Hello World InOutput One <HelloWorld>] : CheckInOutputMessageBusPrepared(const MessageBus&)
11[Hello World InOutput Two <HelloWorld>] : CheckInOutputMessageBusPrepared(const MessageBus&)
12[Hello World InOutput One <HelloWorld>] : PrepareTaskMessageBus(const Task& task, MessageBus&)
13[Hello World InOutput Two <HelloWorld>] : PrepareTaskMessageBus(const Task& task, MessageBus&)
14[Hello World Step One <HelloWorld>] : PrepareTaskMessageBus(const Task& task, MessageBus&)
15[Hello World Step Two <HelloWorld>] : PrepareTaskMessageBus(const Task& task, MessageBus&)
16[Hello World InOutput One <HelloWorld>] : PrepareTaskMessageBus(const Task& task, MessageBus&)
17[Hello World InOutput Two <HelloWorld>] : PrepareTaskMessageBus(const Task& task, MessageBus&)
18[Hello World Step One <HelloWorld>] : PrepareTaskMessageBus(const Task& task, MessageBus&)
19[Hello World Step Two <HelloWorld>] : PrepareTaskMessageBus(const Task& task, MessageBus&)
20[Hello World InOutput One <HelloWorld>] : PrepareTaskMessageBus(const Task& task, MessageBus&)
21[Hello World InOutput Two <HelloWorld>] : PrepareTaskMessageBus(const Task& task, MessageBus&)
22[Hello World Step One <HelloWorld>] : PrepareTaskMessageBus(const Task& task, MessageBus&)
23[Hello World Step Two <HelloWorld>] : PrepareTaskMessageBus(const Task& task, MessageBus&)
24[Hello World InOutput One <HelloWorld>] : CheckTaskMessageBusPrepared(const Task& task, const MessageBus&)
25[Hello World InOutput Two <HelloWorld>] : CheckTaskMessageBusPrepared(const Task& task, const MessageBus&)
26[Hello World Step One <HelloWorld>] : CheckTaskMessageBusPrepared(const Task& task, const MessageBus&)
27[Hello World Step Two <HelloWorld>] : CheckTaskMessageBusPrepared(const Task& task, const MessageBus&)
28[Hello World InOutput One <HelloWorld>] : CheckTaskMessageBusPrepared(const Task& task, const MessageBus&)
29[Hello World InOutput Two <HelloWorld>] : CheckTaskMessageBusPrepared(const Task& task, const MessageBus&)
30[Hello World Step One <HelloWorld>] : CheckTaskMessageBusPrepared(const Task& task, const MessageBus&)
31[Hello World Step Two <HelloWorld>] : CheckTaskMessageBusPrepared(const Task& task, const MessageBus&)
32[Hello World InOutput One <HelloWorld>] : CheckTaskMessageBusPrepared(const Task& task, const MessageBus&)
33[Hello World InOutput Two <HelloWorld>] : CheckTaskMessageBusPrepared(const Task& task, const MessageBus&)
34[Hello World Step One <HelloWorld>] : CheckTaskMessageBusPrepared(const Task& task, const MessageBus&)
35[Hello World Step Two <HelloWorld>] : CheckTaskMessageBusPrepared(const Task& task, const MessageBus&)
36[Hello World Step One <HelloWorld>] : Prepare(Task&)
37[Hello World Step Two <HelloWorld>] : Prepare(Task&)
38[Hello World InOutput One <HelloWorld>] : Prepare()
39[Hello World InOutput Two <HelloWorld>] : Prepare()
40[Pipeline <Pipeline>] : Prepared pipeline. Safety status is SAFE.
41[Main <main>] : The next sample is a MainTick! Both Tick and MainTick should be called.
42[Main <main>] : ==== Start sample 0 ====
43[Pipeline <Pipeline>] : Main state changed.
44State machine state: BOOTING
45 Hello World InOutput One BOOTING NONE
46 Hello World InOutput Two BOOTING NONE
47 Hello World Step One BOOTING NONE
48 Hello World Step Two BOOTING NONE
49
50[Hello World InOutput One <HelloWorld>] : Tick()
51[Hello World InOutput Two <HelloWorld>] : Tick()
52[Hello World InOutput One <HelloWorld>] : MainTick()
53[Hello World InOutput Two <HelloWorld>] : MainTick()
54[Hello World Step One <HelloWorld>] : MainTick(DataBucket&)
55[Hello World Step Two <HelloWorld>] : MainTick(DataBucket&)
56[Hello World InOutput One <HelloWorld>] : TaskCompleted()
57[Hello World InOutput Two <HelloWorld>] : TaskCompleted()
58[Main <main>] : ==== End sample 0 ====
59[Main <main>] : The next sample is a Tick! Only Tick should be called.
60[Main <main>] : ==== Start sample 1 ====
61[Hello World InOutput One <HelloWorld>] : Tick()
62[Hello World InOutput Two <HelloWorld>] : Tick()
63[Main <main>] : ==== End sample 1 ====
64[Main <main>] : The next sample is a Tick! Only Tick should be called.
65[Main <main>] : ==== Start sample 2 ====
66[Hello World InOutput One <HelloWorld>] : Tick()
67[Hello World InOutput Two <HelloWorld>] : Tick()
68[Main <main>] : ==== End sample 2 ====
69[Main <main>] : The next sample is a MainTick! Both Tick and MainTick should be called.
70[Main <main>] : ==== Start sample 3 ====
71[Pipeline <Pipeline>] : Client state(s) changed.
72State machine state: BOOTING
73 Hello World InOutput One BOOTING BOOTED
74 Hello World InOutput Two BOOTING BOOTED
75 Hello World Step One BOOTING BOOTED
76 Hello World Step Two BOOTING BOOTED
77
78[Pipeline <Pipeline>] : Main state changed.
79State machine state: IDLE
80 Hello World InOutput One IDLE NONE
81 Hello World InOutput Two IDLE NONE
82 Hello World Step One IDLE NONE
83 Hello World Step Two IDLE NONE
84
85[Hello World InOutput One <HelloWorld>] : Tick()
86[Hello World InOutput Two <HelloWorld>] : Tick()
87[Hello World InOutput One <HelloWorld>] : MainTick()
88[Hello World InOutput Two <HelloWorld>] : MainTick()
89[Hello World Step One <HelloWorld>] : MainTick(DataBucket&)
90[Hello World Step Two <HelloWorld>] : MainTick(DataBucket&)
91[Hello World InOutput One <HelloWorld>] : TaskCompleted()
92[Hello World InOutput Two <HelloWorld>] : TaskCompleted()
93[Main <main>] : ==== End sample 3 ====
94[Main <main>] : The next sample is a Tick! Only Tick should be called.
95[Main <main>] : ==== Start sample 4 ====
96[Hello World InOutput One <HelloWorld>] : Tick()
97[Hello World InOutput Two <HelloWorld>] : Tick()
98[Main <main>] : ==== End sample 4 ====
99[Main <main>] : The next sample is a Tick! Only Tick should be called.
100[Main <main>] : ==== Start sample 5 ====
101[Hello World InOutput One <HelloWorld>] : Tick()
102[Hello World InOutput Two <HelloWorld>] : Tick()
103[Main <main>] : ==== End sample 5 ====
104[Main <main>] : The next sample is a MainTick! Both Tick and MainTick should be called.
105[Main <main>] : ==== Start sample 6 ====
106[Hello World InOutput One <HelloWorld>] : Tick()
107[Hello World InOutput Two <HelloWorld>] : Tick()
108[Hello World InOutput One <HelloWorld>] : MainTick()
109[Hello World InOutput Two <HelloWorld>] : MainTick()
110[Hello World Step One <HelloWorld>] : MainTick(DataBucket&)
111[Hello World Step Two <HelloWorld>] : MainTick(DataBucket&)
112[Hello World InOutput One <HelloWorld>] : TaskCompleted()
113[Hello World InOutput Two <HelloWorld>] : TaskCompleted()
114[Main <main>] : ==== End sample 6 ====
115[Pipeline <Pipeline>] : Time measurement results for InOutput tick calls:
116 tick:Hello World InOutput One [us] min:
117 tick:Hello World InOutput Two [us] min:
118[Pipeline <Pipeline>] : Time measurement results for InOutput MainTick calls:
119 MainTick:Hello World InOutput One [us] min:
120 MainTick:Hello World InOutput Two [us] min:
121[Pipeline <Pipeline>] : Time measurement results for InOutput taskCompleted calls:
122 taskCompleted:Hello World InOutput One [us] min:
123 taskCompleted:Hello World InOutput Two [us] min:
124[Task <Task>] : Time measurement information for task Task:
125 Task:MainTick:Hello World Step One [ms] min:
126 Task:MainTick:Hello World Step Two [ms] min:
127[Hello World Step One <HelloWorld>] : Destructor
128[Hello World Step Two <HelloWorld>] : Destructor
129[Hello World InOutput One <HelloWorld>] : ~HelloWorld()
130[Hello World InOutput Two <HelloWorld>] : ~HelloWorld()
Observe the following:
- Directly following the constructor calls, note that a lot of calls to
PrepareTaskMessageBus
andCheckTaskMessageBusPrepared
are performed. This is not by mistake! That is, for each 'buffer element', a separateTaskMessageBus
needs to be initialized and prepared. The optioncommand_buffer_length
is set to 3, and so threeTaskMessageBus
instances need to be prepared, once by eachInOutput
andStep
instance. - The first sample is immediately both a
Tick
and aMainTick
! - At the start of the program, the
InOutput
andStep
instances are all inBOOTING
, and declare themselvesBOOTED
. - In this example, a
Task
withStep
instances is added to thePipeline
, therefore, theMainTick()
function on theInOutput
instances is called. - The global
StateMachine
will only change states on aMainTick
! This prevents (under normal circumstances), that the global state changes while some expensive computations are performed in theTask::MainTick()
.
Example 3 - StateMachine demo#
In the third example, we also add an InOutput
of type GoToRun
, which will move the StateMachine
to the RUN
state and back to IDLE
, see this page.
1void Example3(mpmca::utilities::Logger& logger)
2{
3 using namespace mpmca;
4
5 pipeline::Pipeline::Options pipeline_options;
6 pipeline_options.mark_nondeterministic_log_output = true;
7 pipeline::Pipeline pipeline{pipeline_options};
8
9 pipeline.AddInOutput<pipeline::in_output::HelloWorld>(
10 "Hello World InOutput One", false);
11 pipeline.AddInOutput<pipeline::in_output::HelloWorld>(
12 "Hello World InOutput Two", false);
13 auto go_to_run_inoutput =
14 pipeline.AddInOutput<pipeline::in_output::GoToRun>(
15 "Go To Run InOutput");
16 pipeline.AddInOutput<pipeline::in_output::DelayedStateFollower>(
17 "Delayed Follower", 2);
18
19 auto task = pipeline.MakeTask("Task", utilities::Horizon(3, 50));
20
21 task->AddStep<pipeline::step::HelloWorld>("Hello World Step One", false);
22 task->AddStep<pipeline::step::HelloWorld>("Hello World Step Two", false);
23
24 pipeline.Prepare();
25
26 for (size_t t = 0; t < 18; ++t) {
27 logger.Info("==== Start sample " + std::to_string(t) + " ====");
28
29 pipeline.Tick();
30
31 if (pipeline.GetCurrentTickIsMainTick(0))
32 pipeline.MainTick(0);
33
34 logger.Info("==== End sample " + std::to_string(t) + " ====");
35 }
36
37 // After reaching state kRun on the 17th sample, we tell the GoToRunInOutput
38 // to command the StateMachine back to IDLE.
39 go_to_run_inoutput->SetTargetState(
40 pipeline::in_output::GoToRun::TargetState::kIdle);
41
42 for (size_t t = 18; t < 25; ++t) {
43 logger.Info("==== Start sample " + std::to_string(t) + " ====");
44
45 pipeline.Tick();
46
47 if (pipeline.GetCurrentTickIsMainTick(0))
48 pipeline.MainTick(0);
49
50 logger.Info("==== End sample " + std::to_string(t) + " ====");
51 }
52}
Run this example, by running ./demo_hello_pipeline --run_example3
.
The expected output is as follows:
1[Main <main>] : <<<<< Example 3 >>>>>
2[Task <Task>] : This Task will tick once every 3 base ticks.
3[Task <Task>] : The total horizon length of this Task is 150 ms and has 50 steps.
4[Pipeline <Pipeline>] : Prepared pipeline. Safety status is SAFE.
5[Main <main>] : ==== Start sample 0 ====
6[Pipeline <Pipeline>] : Main state changed.
7State machine state: BOOTING
8 Hello World InOutput One BOOTING NONE
9 Hello World InOutput Two BOOTING NONE
10 Go To Run InOutput BOOTING NONE
11 Delayed Follower BOOTING NONE
12 Hello World Step One BOOTING NONE
13 Hello World Step Two BOOTING NONE
14
15[Main <main>] : ==== End sample 0 ====
16[Main <main>] : ==== Start sample 1 ====
17[Main <main>] : ==== End sample 1 ====
18[Main <main>] : ==== Start sample 2 ====
19[Main <main>] : ==== End sample 2 ====
20[Main <main>] : ==== Start sample 3 ====
21[Pipeline <Pipeline>] : Client state(s) changed.
22State machine state: BOOTING
23 Hello World InOutput One BOOTING BOOTED
24 Hello World InOutput Two BOOTING BOOTED
25 Go To Run InOutput BOOTING BOOTED
26 Delayed Follower BOOTING BOOTED
27 Hello World Step One BOOTING BOOTED
28 Hello World Step Two BOOTING BOOTED
29
30[Pipeline <Pipeline>] : Main state changed.
31State machine state: IDLE
32 Hello World InOutput One IDLE NONE
33 Hello World InOutput Two IDLE NONE
34 Go To Run InOutput IDLE NONE
35 Delayed Follower IDLE NONE
36 Hello World Step One IDLE NONE
37 Hello World Step Two IDLE NONE
38
39[Main <main>] : ==== End sample 3 ====
40[Main <main>] : ==== Start sample 4 ====
41[Main <main>] : ==== End sample 4 ====
42[Main <main>] : ==== Start sample 5 ====
43[Main <main>] : ==== End sample 5 ====
44[Main <main>] : ==== Start sample 6 ====
45[Pipeline <Pipeline>] : Client state(s) changed.
46State machine state: IDLE
47 Hello World InOutput One IDLE NONE
48 Hello World InOutput Two IDLE NONE
49 Go To Run InOutput IDLE PREPARING
50 Delayed Follower IDLE NONE
51 Hello World Step One IDLE NONE
52 Hello World Step Two IDLE NONE
53
54[Pipeline <Pipeline>] : Main state changed.
55State machine state: PREPARING
56 Hello World InOutput One PREPARING NONE
57 Hello World InOutput Two PREPARING NONE
58 Go To Run InOutput PREPARING NONE
59 Delayed Follower PREPARING NONE
60 Hello World Step One PREPARING NONE
61 Hello World Step Two PREPARING NONE
62
63[Main <main>] : ==== End sample 6 ====
64[Main <main>] : ==== Start sample 7 ====
65[Main <main>] : ==== End sample 7 ====
66[Main <main>] : ==== Start sample 8 ====
67[Main <main>] : ==== End sample 8 ====
68[Main <main>] : ==== Start sample 9 ====
69[Pipeline <Pipeline>] : Client state(s) changed.
70State machine state: PREPARING
71 Hello World InOutput One PREPARING PREPARED
72 Hello World InOutput Two PREPARING PREPARED
73 Go To Run InOutput PREPARING PREPARED
74 Delayed Follower PREPARING PREPARED
75 Hello World Step One PREPARING PREPARED
76 Hello World Step Two PREPARING PREPARED
77
78[Pipeline <Pipeline>] : Main state changed.
79State machine state: READY
80 Hello World InOutput One READY NONE
81 Hello World InOutput Two READY NONE
82 Go To Run InOutput READY NONE
83 Delayed Follower READY NONE
84 Hello World Step One READY NONE
85 Hello World Step Two READY NONE
86
87[Main <main>] : ==== End sample 9 ====
88[Main <main>] : ==== Start sample 10 ====
89[Main <main>] : ==== End sample 10 ====
90[Main <main>] : ==== Start sample 11 ====
91[Main <main>] : ==== End sample 11 ====
92[Main <main>] : ==== Start sample 12 ====
93[Pipeline <Pipeline>] : Client state(s) changed.
94State machine state: READY
95 Hello World InOutput One READY NONE
96 Hello World InOutput Two READY NONE
97 Go To Run InOutput READY STARTING
98 Delayed Follower READY NONE
99 Hello World Step One READY NONE
100 Hello World Step Two READY NONE
101
102[Pipeline <Pipeline>] : Main state changed.
103State machine state: STARTING
104 Hello World InOutput One STARTING NONE
105 Hello World InOutput Two STARTING NONE
106 Go To Run InOutput STARTING NONE
107 Delayed Follower STARTING NONE
108 Hello World Step One STARTING NONE
109 Hello World Step Two STARTING NONE
110
111[Main <main>] : ==== End sample 12 ====
112[Main <main>] : ==== Start sample 13 ====
113[Main <main>] : ==== End sample 13 ====
114[Main <main>] : ==== Start sample 14 ====
115[Main <main>] : ==== End sample 14 ====
116[Main <main>] : ==== Start sample 15 ====
117[Pipeline <Pipeline>] : Client state(s) changed.
118State machine state: STARTING
119 Hello World InOutput One STARTING STARTED
120 Hello World InOutput Two STARTING STARTED
121 Go To Run InOutput STARTING STARTED
122 Delayed Follower STARTING STARTED
123 Hello World Step One STARTING STARTED
124 Hello World Step Two STARTING STARTED
125
126[Pipeline <Pipeline>] : Main state changed.
127State machine state: RUN
128 Hello World InOutput One RUN NONE
129 Hello World InOutput Two RUN NONE
130 Go To Run InOutput RUN NONE
131 Delayed Follower RUN NONE
132 Hello World Step One RUN NONE
133 Hello World Step Two RUN NONE
134
135[Main <main>] : ==== End sample 15 ====
136[Main <main>] : ==== Start sample 16 ====
137[Main <main>] : ==== End sample 16 ====
138[Main <main>] : ==== Start sample 17 ====
139[Main <main>] : ==== End sample 17 ====
140[Main <main>] : ==== Start sample 18 ====
141[Main <main>] : ==== End sample 18 ====
142[Main <main>] : ==== Start sample 19 ====
143[Main <main>] : ==== End sample 19 ====
144[Main <main>] : ==== Start sample 20 ====
145[Main <main>] : ==== End sample 20 ====
146[Main <main>] : ==== Start sample 21 ====
147[Pipeline <Pipeline>] : Client state(s) changed.
148State machine state: RUN
149 Hello World InOutput One RUN NONE
150 Hello World InOutput Two RUN NONE
151 Go To Run InOutput RUN STOPPING
152 Delayed Follower RUN NONE
153 Hello World Step One RUN NONE
154 Hello World Step Two RUN NONE
155
156[Pipeline <Pipeline>] : Main state changed.
157State machine state: STOPPING
158 Hello World InOutput One STOPPING NONE
159 Hello World InOutput Two STOPPING NONE
160 Go To Run InOutput STOPPING NONE
161 Delayed Follower STOPPING NONE
162 Hello World Step One STOPPING NONE
163 Hello World Step Two STOPPING NONE
164
165[Main <main>] : ==== End sample 21 ====
166[Main <main>] : ==== Start sample 22 ====
167[Main <main>] : ==== End sample 22 ====
168[Main <main>] : ==== Start sample 23 ====
169[Main <main>] : ==== End sample 23 ====
170[Main <main>] : ==== Start sample 24 ====
171[Pipeline <Pipeline>] : Client state(s) changed.
172State machine state: STOPPING
173 Hello World InOutput One STOPPING STOPPED
174 Hello World InOutput Two STOPPING STOPPED
175 Go To Run InOutput STOPPING STOPPED
176 Delayed Follower STOPPING STOPPED
177 Hello World Step One STOPPING STOPPED
178 Hello World Step Two STOPPING STOPPED
179
180[Pipeline <Pipeline>] : Main state changed.
181State machine state: IDLE
182 Hello World InOutput One IDLE NONE
183 Hello World InOutput Two IDLE NONE
184 Go To Run InOutput IDLE NONE
185 Delayed Follower IDLE NONE
186 Hello World Step One IDLE NONE
187 Hello World Step Two IDLE NONE
188
189[Main <main>] : ==== End sample 24 ====
190[Pipeline <Pipeline>] : Time measurement results for InOutput tick calls:
191 tick:Hello World InOutput One [us] min:
192 tick:Hello World InOutput Two [us] min:
193 tick:Go To Run InOutput [us] min:
194 tick:Delayed Follower [us] min:
195[Pipeline <Pipeline>] : Time measurement results for InOutput MainTick calls:
196 MainTick:Hello World InOutput One [us] min:
197 MainTick:Hello World InOutput Two [us] min:
198 MainTick:Go To Run InOutput [us] min:
199 MainTick:Delayed Follower [us] min:
200[Pipeline <Pipeline>] : Time measurement results for InOutput taskCompleted calls:
201 taskCompleted:Hello World InOutput One [us] min:
202 taskCompleted:Hello World InOutput Two [us] min:
203 taskCompleted:Go To Run InOutput [us] min:
204 taskCompleted:Delayed Follower [us] min:
205[Task <Task>] : Time measurement information for task Task:
206 Task:MainTick:Hello World Step One [ms] min:
207 Task:MainTick:Hello World Step Two [ms] min:
Observe that:
- The states follow the state flow as depicted here.
- The global state only changes on
MainTick
s.