| Prev | Getting Started – Table of Contents | Next |
Part 3: Customizing Simulation Output
In Part 2 you created a node called square_wave_closed_system
that used the standard output stream std::cout
to produce the following output.
y = 0
y = 1
y = 0
y = 1
y = 0
y = 1
y = 0
y = 1
y = 0
y = 1
y = 0
y = 1
However the use of std::cout
within a node is not recommended practice. One problem with std::cout
is that it does not indicate the point in simulated time at which each output occurred. Let’s find a better way to extract information from the simulation.
Find the file square_wave_closed_system.h and delete the following line of code, which imports the standard output stream.
#include <iostream>
Now, find the line below…
std::cout << "y = " << float64(phase) << std::endl;
…and replace it with the following and save.
print((string_builder() << "y = " << float64(phase)).str());
Here the string_builder
object is used to create a std::string
value of the form "y = #"
. The print
function outputs the string along with contextual information about the simulation. If you rebuild and run the first_simulation
executable, you should see the following output.
0|0|$time:time_point()
0|0|top$print:y = 0
1|0|$time:time_point() + 7_s
1|0|top$print:y = 1
2|0|$time:time_point() + 10_s
2|0|top$print:y = 0
3|0|$time:time_point() + 17_s
3|0|top$print:y = 1
4|0|$time:time_point() + 20_s
4|0|top$print:y = 0
5|0|$time:time_point() + 27_s
5|0|top$print:y = 1
6|0|$time:time_point() + 30_s
6|0|top$print:y = 0
7|0|$time:time_point() + 37_s
7|0|top$print:y = 1
8|0|$time:time_point() + 40_s
8|0|top$print:y = 0
9|0|$time:time_point() + 47_s
9|0|top$print:y = 1
10|0|$time:time_point() + 50_s
10|0|top$print:y = 0
11|0|$time:time_point() + 57_s
11|0|top$print:y = 1
Notice that each row begins with two numbers. The first number associates each row with a particular point in simulated time. The rows that begin with 0, for example, are associated with the time at the beginning of the simulation. The rows that begin with 3 are associated with the time point at 17 seconds from the beginning. The second number is a counter of steps within each time point, starting from 0. In this example, there is only one step per time point, so the counter is always at 0.
We still see the printed text "y = 0"
or "y = 1"
, but it is associated with a node named top
. This is the name that is always given to the top-level node in a simulation. In this example, the top node is the only node, but in more complex examples it is useful to see which node produced each output.
Although using the print
function is recommended over using std::cout
, it is still not the best practice. Ideally, the signal level would be made available through a message output port, and operations outside of the node would determine how the values are presented. This will be covered in the next part of the tutorial.
Let’s explore one more output customization feature.
In the square_wave.h file, find the instruction…
sim.process_remaining_events();
…and immediately above it insert the following line and save.
sim.top.print_on_event();
Now when the first_simulation
executable is rebuilt and run, the type of each event is printed. You can see that the initialization
event occurs first, followed by a succession of planned
events, followed by the finalization
event. This extra information helps one locate the function responsible for each printed value.
0|0|$time:time_point()
0|0|top$initialization
0|1|top$planned
0|1|top$print:y = 0
1|0|$time:time_point() + 7_s
1|0|top$planned
1|0|top$print:y = 1
2|0|$time:time_point() + 10_s
2|0|top$planned
2|0|top$print:y = 0
3|0|$time:time_point() + 17_s
3|0|top$planned
3|0|top$print:y = 1
4|0|$time:time_point() + 20_s
4|0|top$planned
4|0|top$print:y = 0
5|0|$time:time_point() + 27_s
5|0|top$planned
5|0|top$print:y = 1
6|0|$time:time_point() + 30_s
6|0|top$planned
6|0|top$print:y = 0
7|0|$time:time_point() + 37_s
7|0|top$planned
7|0|top$print:y = 1
8|0|$time:time_point() + 40_s
8|0|top$planned
8|0|top$print:y = 0
9|0|$time:time_point() + 47_s
9|0|top$planned
9|0|top$print:y = 1
10|0|$time:time_point() + 50_s
10|0|top$planned
10|0|top$print:y = 0
11|0|$time:time_point() + 57_s
11|0|top$planned
11|0|top$print:y = 1
12|0|$time:time_point() + 60_s
12|0|top$finalization
The print
and print_on_event
features are just two of several mechanisms that SyDEVS provides for customizing simulation output. In Part 4, you’ll learn how to take a node and give it a set of ports, which opens up additional possibilities for communicating data.
Continue to Part 4 |