A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
time-probe-example.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014 University of Washington
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7//
8// This example is designed to show the main features of an ns3::TimeProbe.
9// A test object is used to emit values through a trace source. The
10// example shows three ways to use a ns3::TimeProbe to hook the output
11// of this trace source (in addition to hooking the raw trace source).
12//
13// It produces two types of output. By default, it will generate a
14// gnuplot of interarrival times. If the '--verbose=1' argument is passed,
15// it will also generate debugging output of the form (for example):
16//
17// Emitting at 96.5378 seconds
18// context: raw trace source old 0.293343 new 0.00760254
19// context: probe1 old 0.293343 new 0.00760254
20// context: probe2 old 0.293343 new 0.00760254
21// context: probe3 old 0.293343 new 0.00760254
22//
23// The stopTime defaults to 100 seconds but can be changed by an argument.
24//
25
26#include "ns3/core-module.h"
27#include "ns3/gnuplot-helper.h"
28#include "ns3/time-probe.h"
29
30#include <string>
31
32using namespace ns3;
33
34NS_LOG_COMPONENT_DEFINE("TimeProbeExample");
35
36/**
37 * This is our test object, an object that emits values according to
38 * a Poisson arrival process. It emits a traced Time value as a
39 * trace source; this takes the value of interarrival time
40 */
41class Emitter : public Object
42{
43 public:
44 /**
45 * Register this type.
46 * \return The TypeId.
47 */
48 static TypeId GetTypeId();
50
51 private:
52 void DoInitialize() override;
53 /// Generate data.
54 void Emit();
55
56 TracedValue<Time> m_interval; //!< Interarrival time between events.
57 Time m_last; //!< Current interarrival time.
58 Ptr<ExponentialRandomVariable> m_var; //!< Random number generator.
59};
60
62
65{
66 static TypeId tid = TypeId("ns3::Emitter")
68 .SetGroupName("Stats")
69 .AddConstructor<Emitter>()
70 .AddTraceSource("Interval",
71 "Trace source",
73 "ns3::TracedValueCallback::Time");
74 return tid;
75}
76
78 : m_interval(Seconds(0)),
79 m_last(Seconds(0))
80{
82}
83
84void
86{
87 Simulator::Schedule(Seconds(m_var->GetValue()), &Emitter::Emit, this);
88}
89
90void
92{
93 NS_LOG_DEBUG("Emitting at " << Simulator::Now().As(Time::S));
96 TimeProbe::SetValueByPath("/Names/probe3", m_interval);
97 Simulator::Schedule(Seconds(m_var->GetValue()), &Emitter::Emit, this);
98}
99
100// This is a function to test hooking a raw function to the trace source
101void
102NotifyViaTraceSource(std::string context, Time oldVal, Time newVal)
103{
106 if (verbose.Get())
107 {
108 std::cout << "context: " << context << " old " << oldVal.As(Time::S) << " new "
109 << newVal.As(Time::S) << std::endl;
110 }
111}
112
113// This is a function to test hooking it to the probe output
114void
115NotifyViaProbe(std::string context, double oldVal, double newVal)
116{
119 if (verbose.Get())
120 {
121 std::cout << "context: " << context << " old " << oldVal << " new " << newVal << std::endl;
122 }
123}
124
126 "Whether to enable verbose output",
127 ns3::BooleanValue(false),
129
130int
131main(int argc, char* argv[])
132{
133 double stopTime = 100.0;
134 bool verbose = false;
135
136 CommandLine cmd(__FILE__);
137 cmd.AddValue("stopTime", "Time (seconds) to terminate simulation", stopTime);
138 cmd.AddValue("verbose", "Whether to enable verbose output", verbose);
139 cmd.Parse(argc, argv);
140 bool connected;
141
142 // Set a global value, so that the callbacks can access it
143 if (verbose)
144 {
145 GlobalValue::Bind("verbose", BooleanValue(true));
146 LogComponentEnable("TimeProbeExample", LOG_LEVEL_ALL);
147 }
148
150 Names::Add("/Names/Emitter", emitter);
151
152 //
153 // The below shows typical functionality without a probe
154 // (connect a sink function to a trace source)
155 //
156 connected =
157 emitter->TraceConnect("Interval", "raw trace source", MakeCallback(&NotifyViaTraceSource));
158 NS_ASSERT_MSG(connected, "Trace source not connected");
159
160 //
161 // Next, we'll show several use cases of using a Probe to access and
162 // filter the values of the underlying trace source
163 //
164
165 //
166 // Probe1 will be hooked directly to the Emitter trace source object
167 //
168
169 // probe1 will be hooked to the Emitter trace source
171 // the probe's name can serve as its context in the tracing
172 probe1->SetName("probe1");
173
174 // Connect the probe to the emitter's Interval
175 connected = probe1->ConnectByObject("Interval", emitter);
176 NS_ASSERT_MSG(connected, "Trace source not connected to probe1");
177
178 // The probe itself should generate output. The context that we provide
179 // to this probe (in this case, the probe name) will help to disambiguate
180 // the source of the trace
181 connected = probe1->TraceConnect("Output", probe1->GetName(), MakeCallback(&NotifyViaProbe));
182 NS_ASSERT_MSG(connected, "Trace source not connected to probe1 Output");
183
184 //
185 // Probe2 will be hooked to the Emitter trace source object by
186 // accessing it by path name in the Config database
187 //
188
189 // Create another similar probe; this will hook up via a Config path
191 probe2->SetName("probe2");
192
193 // Note, no return value is checked here
194 probe2->ConnectByPath("/Names/Emitter/Interval");
195
196 // The probe itself should generate output. The context that we provide
197 // to this probe (in this case, the probe name) will help to disambiguate
198 // the source of the trace
199 connected = probe2->TraceConnect("Output", "probe2", MakeCallback(&NotifyViaProbe));
200 NS_ASSERT_MSG(connected, "Trace source not connected to probe2 Output");
201
202 //
203 // Probe3 will be called by the emitter directly through the
204 // static method SetValueByPath().
205 //
207 probe3->SetName("probe3");
208
209 // By adding to the config database, we can access it later
210 Names::Add("/Names/probe3", probe3);
211
212 // The probe itself should generate output. The context that we provide
213 // to this probe (in this case, the probe name) will help to disambiguate
214 // the source of the trace
215 connected = probe3->TraceConnect("Output", "probe3", MakeCallback(&NotifyViaProbe));
216 NS_ASSERT_MSG(connected, "Trace source not connected to probe3 Output");
217
218 // Plot the interval values
219 GnuplotHelper plotHelper;
220 plotHelper.ConfigurePlot("time-probe-example",
221 "Emitter interarrivals vs. Time",
222 "Simulation time (Seconds)",
223 "Interarrival time (Seconds)",
224 "png");
225
226 // Helper creates a TimeProbe and hooks it to the /Names/Emitter/Interval
227 // source. Helper also takes the Output of the TimeProbe and plots it
228 // as a dataset labeled 'Emitter Interarrival Time'
229 plotHelper.PlotProbe("ns3::TimeProbe",
230 "/Names/Emitter/Interval",
231 "Output",
232 "Emitter Interarrival Time",
234
235 // The Emitter object is not associated with an ns-3 node, so
236 // it won't get started automatically, so we need to do this ourselves
238
242
243 return 0;
244}
This is our test object, an object that increments counters at various times and emits one of them as...
void DoInitialize() override
Initialize() implementation.
static TypeId GetTypeId()
Register this type.
void Emit()
Generate data.
static TypeId GetTypeId()
Register this type.
Time m_last
Current interarrival time.
TracedValue< Time > m_interval
Interarrival time between events.
Ptr< ExponentialRandomVariable > m_var
Random number generator.
Parse command-line arguments.
Hold a so-called 'global value'.
static void Bind(std::string name, const AttributeValue &value)
Iterate over the set of GlobalValues until a matching name is found and then set its value with Globa...
static void GetValueByName(std::string name, AttributeValue &value)
Finds the GlobalValue with the given name and returns its value.
Helper class used to make gnuplot plots.
void ConfigurePlot(const std::string &outputFileNameWithoutExtension, const std::string &title, const std::string &xLegend, const std::string &yLegend, const std::string &terminalType="png")
void PlotProbe(const std::string &typeId, const std::string &path, const std::string &probeTraceSource, const std::string &title, GnuplotAggregator::KeyLocation keyLocation=GnuplotAggregator::KEY_INSIDE)
static void Add(std::string name, Ptr< Object > object)
Add the association between the string "name" and the Ptr<Object> obj.
Definition names.cc:764
A base class which provides memory management and object aggregation.
Definition object.h:78
void Initialize()
Invoke DoInitialize on all Objects aggregated to this one.
Definition object.cc:203
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static void Run()
Run the simulation.
Definition simulator.cc:167
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
Simulation virtual time values and global simulation resolution.
Definition nstime.h:94
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition time.cc:404
@ S
second
Definition nstime.h:105
static void SetValueByPath(std::string path, Time value)
Set a probe value by its name in the Config system.
Definition time-probe.cc:68
Trace classes with value semantics.
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Time stopTime
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition boolean.cc:113
void LogComponentEnable(const std::string &name, LogLevel level)
Enable the logging output associated with that log component.
Definition log.cc:291
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:684
@ LOG_LEVEL_ALL
Print everything.
Definition log.h:105
bool verbose
static ns3::GlobalValue g_verbose("verbose", "Whether to enable verbose output", ns3::BooleanValue(false), ns3::MakeBooleanChecker())
void NotifyViaProbe(std::string context, double oldVal, double newVal)
void NotifyViaTraceSource(std::string context, Time oldVal, Time newVal)