satellite-stats-fwd-link-scheduler-symbol-rate-helper.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2019 CNES
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Bastien Tauran <bastien.tauran@viveris.fr>
19  *
20  */
21 
23 
24 #include <ns3/boolean.h>
25 #include <ns3/data-collection-object.h>
26 #include <ns3/distribution-collector.h>
27 #include <ns3/enum.h>
28 #include <ns3/interval-rate-collector.h>
29 #include <ns3/log.h>
30 #include <ns3/magister-gnuplot-aggregator.h>
31 #include <ns3/multi-file-aggregator.h>
32 #include <ns3/node-container.h>
33 #include <ns3/object-map.h>
34 #include <ns3/object-vector.h>
35 #include <ns3/pointer.h>
36 #include <ns3/satellite-fwd-link-scheduler.h>
37 #include <ns3/satellite-gw-mac.h>
38 #include <ns3/satellite-helper.h>
39 #include <ns3/satellite-mac.h>
40 #include <ns3/satellite-net-device.h>
41 #include <ns3/satellite-topology.h>
42 #include <ns3/scalar-collector.h>
43 #include <ns3/singleton.h>
44 #include <ns3/string.h>
45 #include <ns3/unit-conversion-collector.h>
46 
47 #include <sstream>
48 #include <string>
49 
50 NS_LOG_COMPONENT_DEFINE("SatStatsFwdLinkSchedulerSymbolRateHelper");
51 
52 namespace ns3
53 {
54 
55 NS_OBJECT_ENSURE_REGISTERED(SatStatsFwdLinkSchedulerSymbolRateHelper);
56 
58  Ptr<const SatHelper> satHelper)
59  : SatStatsHelper(satHelper),
60  m_traceSinkCallback(
61  MakeCallback(&SatStatsFwdLinkSchedulerSymbolRateHelper::SymbolRateCallback, this))
62 {
63  NS_LOG_FUNCTION(this << satHelper);
64 }
65 
67 {
68  NS_LOG_FUNCTION(this);
69 }
70 
71 TypeId // static
73 {
74  static TypeId tid =
75  TypeId("ns3::SatStatsFwdLinkSchedulerSymbolRateHelper").SetParent<SatStatsHelper>();
76  return tid;
77 }
78 
79 void
81 {
82  NS_LOG_FUNCTION(this << sliceId << " " << symbolRate);
83 
84  Ptr<DataCollectionObject> collector = nullptr;
85 
86  switch (GetIdentifierType())
87  {
89  collector = m_collectors.Get(0);
90  NS_ASSERT_MSG(collector != nullptr, "Unable to find collector with identifier 0");
91  break;
92  }
94  collector = m_collectors.Get(static_cast<uint32_t>(sliceId));
95  NS_ASSERT_MSG(collector != nullptr, "Unable to find collector with identifier " << sliceId);
96  break;
97  }
98  default:
99  NS_FATAL_ERROR("SatStatsFwdLinkSchedulerSymbolRateHelper - Invalid identifier type");
100  break;
101  }
102 
103  switch (GetOutputType())
104  {
107  Ptr<ScalarCollector> c = collector->GetObject<ScalarCollector>();
108  NS_ASSERT(c != nullptr);
109  c->TraceSinkDouble(0.0, symbolRate);
110  break;
111  }
112 
115  Ptr<IntervalRateCollector> c = collector->GetObject<IntervalRateCollector>();
116  NS_ASSERT(c != nullptr);
117  c->TraceSinkDouble(0.0, symbolRate);
118  break;
119  }
120 
127  Ptr<DistributionCollector> c = collector->GetObject<DistributionCollector>();
128  NS_ASSERT(c != nullptr);
129  c->TraceSinkDouble(0.0, symbolRate);
130  break;
131  }
132 
133  default:
134  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
135  << " is not a valid output type for this statistics.");
136  break;
137 
138  } // end of `switch (GetOutputType ())`
139 
140 } // end of `void RxPowerCallback (double);`
141 
142 Callback<void, uint8_t, double>
144 {
145  return m_traceSinkCallback;
146 }
147 
148 void
150 {
151  NS_LOG_FUNCTION(this);
152 
153  switch (GetOutputType())
154  {
156  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
157  << " is not a valid output type for this statistics.");
158  break;
159 
161  // Setup aggregator.
162  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
163  "OutputFileName",
164  StringValue(GetOutputFileName()),
165  "MultiFileMode",
166  BooleanValue(false),
167  "EnableContextPrinting",
168  BooleanValue(true),
169  "GeneralHeading",
170  StringValue(GetIdentifierHeading("symbol_rate_baud")));
171  Ptr<MultiFileAggregator> aggregator = m_aggregator->GetObject<MultiFileAggregator>();
172 
173  // Setup collectors.
174  m_collectors.SetType("ns3::ScalarCollector");
175  m_collectors.SetAttribute("InputDataType",
176  EnumValue(ScalarCollector::INPUT_DATA_TYPE_DOUBLE));
177  m_collectors.SetAttribute("OutputType",
178  EnumValue(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SECOND));
180  m_collectors.ConnectToAggregator("Output", m_aggregator, &MultiFileAggregator::Write1d);
181 
182  break;
183  }
184 
186  // Setup aggregator.
187  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
188  "OutputFileName",
189  StringValue(GetOutputFileName()),
190  "GeneralHeading",
191  StringValue(GetTimeHeading("symbol_rate_baud")));
192  Ptr<MultiFileAggregator> aggregator = m_aggregator->GetObject<MultiFileAggregator>();
193 
194  // Setup collectors
195  m_collectors.SetType("ns3::IntervalRateCollector");
196  m_collectors.SetAttribute("InputDataType",
197  EnumValue(IntervalRateCollector::INPUT_DATA_TYPE_DOUBLE));
199  m_collectors.ConnectToAggregator("OutputWithTime",
200  m_aggregator,
201  &MultiFileAggregator::Write2d);
202  m_collectors.ConnectToAggregator("OutputString",
203  m_aggregator,
204  &MultiFileAggregator::AddContextHeading);
205 
206  break;
207  }
208 
212  // Setup aggregator.
213  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
214  "OutputFileName",
215  StringValue(GetOutputFileName()),
216  "GeneralHeading",
217  StringValue(GetDistributionHeading("symbol_rate_baud")));
218  Ptr<MultiFileAggregator> aggregator = m_aggregator->GetObject<MultiFileAggregator>();
219 
220  // Setup collectors.
221  m_collectors.SetType("ns3::DistributionCollector");
222  DistributionCollector::OutputType_t outputType =
223  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
225  {
226  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
227  }
229  {
230  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
231  }
232  m_collectors.SetAttribute("OutputType", EnumValue(outputType));
234  m_collectors.ConnectToAggregator("Output", m_aggregator, &MultiFileAggregator::Write2d);
235  m_collectors.ConnectToAggregator("OutputString",
236  m_aggregator,
237  &MultiFileAggregator::AddContextHeading);
238  m_collectors.ConnectToAggregator("Warning",
239  m_aggregator,
240  &MultiFileAggregator::EnableContextWarning);
241 
242  break;
243  }
244 
247  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
248  << " is not a valid output type for this statistics.");
249  break;
250 
252  // Setup aggregator.
253  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
254  "OutputPath",
255  StringValue(GetOutputPath()),
256  "OutputFileName",
257  StringValue(GetName()));
258  Ptr<MagisterGnuplotAggregator> plotAggregator =
259  m_aggregator->GetObject<MagisterGnuplotAggregator>();
260  NS_ASSERT(plotAggregator != nullptr);
261  // plot->SetTitle ("");
262  plotAggregator->SetLegend("Time (in seconds)", "Latency (in seconds)");
263  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
264 
265  // Setup collectors.
266  m_collectors.SetType("ns3::IntervalRateCollector");
267  m_collectors.SetAttribute("InputDataType",
268  EnumValue(IntervalRateCollector::INPUT_DATA_TYPE_DOUBLE));
270  for (CollectorMap::Iterator it = m_collectors.Begin(); it != m_collectors.End(); ++it)
271  {
272  const std::string context = it->second->GetName();
273  plotAggregator->Add2dDataset(context, context);
274  }
275  m_collectors.ConnectToAggregator("OutputWithTime",
276  m_aggregator,
277  &MagisterGnuplotAggregator::Write2d);
278 
279  break;
280  }
281 
285  // Setup aggregator.
286  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
287  "OutputPath",
288  StringValue(GetOutputPath()),
289  "OutputFileName",
290  StringValue(GetName()));
291  Ptr<MagisterGnuplotAggregator> plotAggregator =
292  m_aggregator->GetObject<MagisterGnuplotAggregator>();
293  NS_ASSERT(plotAggregator != nullptr);
294  // plot->SetTitle ("");
295  plotAggregator->SetLegend("Latency (in seconds)", "Frequency");
296  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
297 
298  // Setup collectors.
299  m_collectors.SetType("ns3::DistributionCollector");
300  DistributionCollector::OutputType_t outputType =
301  DistributionCollector::OUTPUT_TYPE_HISTOGRAM;
303  {
304  outputType = DistributionCollector::OUTPUT_TYPE_PROBABILITY;
305  }
307  {
308  outputType = DistributionCollector::OUTPUT_TYPE_CUMULATIVE;
309  }
310  m_collectors.SetAttribute("OutputType", EnumValue(outputType));
312  for (CollectorMap::Iterator it = m_collectors.Begin(); it != m_collectors.End(); ++it)
313  {
314  const std::string context = it->second->GetName();
315  plotAggregator->Add2dDataset(context, context);
316  }
317  m_collectors.ConnectToAggregator("Output",
318  m_aggregator,
319  &MagisterGnuplotAggregator::Write2d);
320 
321  break;
322  }
323 
324  default:
325  NS_FATAL_ERROR("SatStatsFwdLinkSchedulerSymbolRateHelper - Invalid output type");
326  break;
327  }
328 
329  // Setup probes and connect them to the collectors.
330  InstallProbes();
331 
332 } // end of `void DoInstall ();`
333 
334 void
336 {
337  NS_LOG_FUNCTION(this);
338 
339  // Connect to trace sources at GW nodes.
340  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
341 
342  for (NodeContainer::Iterator it = gws.Begin(); it != gws.End(); ++it)
343  {
344  NetDeviceContainer devs = GetGwSatNetDevice(*it);
345 
346  for (NetDeviceContainer::Iterator itDev = devs.Begin(); itDev != devs.End(); ++itDev)
347  {
348  Ptr<SatNetDevice> satDev = (*itDev)->GetObject<SatNetDevice>();
349  NS_ASSERT(satDev != nullptr);
350  Ptr<SatMac> satMac = satDev->GetMac();
351  NS_ASSERT(satMac != nullptr);
352  Ptr<SatGwMac> satGwMac = satMac->GetObject<SatGwMac>();
353  NS_ASSERT(satGwMac != nullptr);
354  PointerValue scheduler;
355  satGwMac->GetAttribute("Scheduler", scheduler);
356  Ptr<SatFwdLinkScheduler> fwdLinkScheduler = scheduler.Get<SatFwdLinkScheduler>();
357  NS_ASSERT(fwdLinkScheduler != nullptr);
358 
359  if (!fwdLinkScheduler->TraceConnectWithoutContext("SymbolRate", GetTraceSinkCallback()))
360  {
361  NS_FATAL_ERROR("Error connecting to Symbol Rate trace source"
362  << " of SatFwdLinkScheduler"
363  << " at node ID " << (*it)->GetId() << " device #"
364  << (*itDev)->GetIfIndex());
365  }
366 
367  } // end of `for (NetDeviceCOntainer::Iterator itDev = devs)`
368 
369  } // end of `for (it = gws.Begin (); it != gws.End (); ++it)`
370 }
371 
372 } // end of namespace ns3
GW specific Mac class for Sat Net Devices.
SatNetDevice to be utilized in the UT and GW nodes.
Parent abstract class of all satellite statistics helpers.
static NetDeviceContainer GetGwSatNetDevice(Ptr< Node > gwNode)
IdentifierType_t GetIdentifierType() const
static std::string GetOutputTypeName(OutputType_t outputType)
virtual std::string GetIdentifierHeading(std::string dataLabel) const
virtual std::string GetOutputPath() const
Ptr< DataCollectionObject > CreateAggregator(std::string aggregatorTypeId, std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue())
Create the aggregator according to the output type.
virtual std::string GetOutputFileName() const
Compute the path and file name where statistics output should be written to.
uint32_t CreateCollectorPerIdentifier(CollectorMap &collectorMap) const
Create one collector instance for each identifier in the simulation.
OutputType_t GetOutputType() const
std::string GetName() const
virtual std::string GetTimeHeading(std::string dataLabel) const
virtual std::string GetDistributionHeading(std::string dataLabel) const
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.