satellite-stats-window-load-helper.cc
Go to the documentation of this file.
1 /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2014 Magister Solutions
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: Budiarto Herman <budiarto.herman@magister.fi>
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/log.h>
29 #include <ns3/magister-gnuplot-aggregator.h>
30 #include <ns3/multi-file-aggregator.h>
31 #include <ns3/node.h>
32 #include <ns3/object-map.h>
33 #include <ns3/object-vector.h>
34 #include <ns3/satellite-helper.h>
35 #include <ns3/satellite-orbiter-net-device.h>
36 #include <ns3/satellite-phy-rx-carrier.h>
37 #include <ns3/satellite-phy-rx.h>
38 #include <ns3/satellite-phy.h>
39 #include <ns3/satellite-topology.h>
40 #include <ns3/scalar-collector.h>
41 #include <ns3/singleton.h>
42 #include <ns3/string.h>
43 #include <ns3/unit-conversion-collector.h>
44 
45 #include <sstream>
46 
47 NS_LOG_COMPONENT_DEFINE("SatStatsWindowLoadHelper");
48 
49 namespace ns3
50 {
51 
52 NS_OBJECT_ENSURE_REGISTERED(SatStatsWindowLoadHelper);
53 
55  : SatStatsHelper(satHelper),
56  m_traceSinkCallback(MakeCallback(&SatStatsWindowLoadHelper::WindowLoadCallback, this))
57 {
58  NS_LOG_FUNCTION(this << satHelper);
59 }
60 
62 {
63  NS_LOG_FUNCTION(this);
64 }
65 
66 TypeId // static
68 {
69  static TypeId tid = TypeId("ns3::SatStatsWindowLoadHelper").SetParent<SatStatsHelper>();
70  return tid;
71 }
72 
73 void
75 {
76  NS_LOG_FUNCTION(this << windowLoad);
77 
78  switch (GetOutputType())
79  {
82  Ptr<ScalarCollector> c = m_collector->GetObject<ScalarCollector>();
83  NS_ASSERT(c != nullptr);
84  c->TraceSinkDouble(0.0, windowLoad);
85  break;
86  }
87 
90  Ptr<UnitConversionCollector> c = m_collector->GetObject<UnitConversionCollector>();
91  NS_ASSERT(c != nullptr);
92  c->TraceSinkDouble(0.0, windowLoad);
93  break;
94  }
95 
102  Ptr<DistributionCollector> c = m_collector->GetObject<DistributionCollector>();
103  NS_ASSERT(c != nullptr);
104  c->TraceSinkDouble(0.0, windowLoad);
105  break;
106  }
107 
108  default:
109  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
110  << " is not a valid output type for this statistics.");
111  break;
112 
113  } // end of `switch (GetOutputType ())`
114 
115 } // end of `void RxPowerCallback (double);`
116 
117 Callback<void, double>
119 {
120  return m_traceSinkCallback;
121 }
122 
123 void
125 {
126  NS_LOG_FUNCTION(this);
127 
128  switch (GetOutputType())
129  {
131  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
132  << " is not a valid output type for this statistics.");
133  break;
134 
136  // Setup aggregator.
137  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
138  "OutputFileName",
139  StringValue(GetOutputFileName()),
140  "MultiFileMode",
141  BooleanValue(false),
142  "EnableContextPrinting",
143  BooleanValue(true),
144  "GeneralHeading",
145  StringValue(GetIdentifierHeading("window_load")));
146  Ptr<MultiFileAggregator> aggregator = m_aggregator->GetObject<MultiFileAggregator>();
147 
148  // Setup collector.
149  Ptr<ScalarCollector> collector = CreateObject<ScalarCollector>();
150  collector->SetName("0");
151  collector->SetInputDataType(ScalarCollector::INPUT_DATA_TYPE_DOUBLE);
152  collector->SetOutputType(ScalarCollector::OUTPUT_TYPE_AVERAGE_PER_SAMPLE);
153  collector->TraceConnect("Output",
154  "0",
155  MakeCallback(&MultiFileAggregator::Write1d, aggregator));
156  m_collector = collector->GetObject<DataCollectionObject>();
157 
158  break;
159  }
160 
162  // Setup aggregator.
163  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
164  "OutputFileName",
165  StringValue(GetOutputFileName()),
166  "GeneralHeading",
167  StringValue(GetTimeHeading("window_load")));
168  Ptr<MultiFileAggregator> aggregator = m_aggregator->GetObject<MultiFileAggregator>();
169 
170  // Setup collector.
171  Ptr<UnitConversionCollector> collector = CreateObject<UnitConversionCollector>();
172  collector->SetName("0");
173  collector->SetConversionType(UnitConversionCollector::TRANSPARENT);
174  collector->TraceConnect("OutputTimeValue",
175  "0",
176  MakeCallback(&MultiFileAggregator::Write2d, aggregator));
177  m_collector = collector->GetObject<DataCollectionObject>();
178 
179  break;
180  }
181 
185  // Setup aggregator.
186  m_aggregator = CreateAggregator("ns3::MultiFileAggregator",
187  "OutputFileName",
188  StringValue(GetOutputFileName()),
189  "GeneralHeading",
190  StringValue(GetDistributionHeading("window_load")));
191  Ptr<MultiFileAggregator> aggregator = m_aggregator->GetObject<MultiFileAggregator>();
192 
193  // Setup collector.
194  Ptr<DistributionCollector> collector = CreateObject<DistributionCollector>();
195  collector->SetName("0");
197  {
198  collector->SetOutputType(DistributionCollector::OUTPUT_TYPE_HISTOGRAM);
199  }
201  {
202  collector->SetOutputType(DistributionCollector::OUTPUT_TYPE_PROBABILITY);
203  }
205  {
206  collector->SetOutputType(DistributionCollector::OUTPUT_TYPE_CUMULATIVE);
207  }
208  collector->TraceConnect("Output",
209  "0",
210  MakeCallback(&MultiFileAggregator::Write2d, aggregator));
211  collector->TraceConnect("OutputString",
212  "0",
213  MakeCallback(&MultiFileAggregator::AddContextHeading, aggregator));
214  collector->TraceConnect(
215  "Warning",
216  "0",
217  MakeCallback(&MultiFileAggregator::EnableContextWarning, aggregator));
218  m_collector = collector->GetObject<DataCollectionObject>();
219 
220  break;
221  }
222 
225  NS_FATAL_ERROR(GetOutputTypeName(GetOutputType())
226  << " is not a valid output type for this statistics.");
227  break;
228 
230  // Setup aggregator.
231  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
232  "OutputPath",
233  StringValue(GetOutputPath()),
234  "OutputFileName",
235  StringValue(GetName()));
236  Ptr<MagisterGnuplotAggregator> plotAggregator =
237  m_aggregator->GetObject<MagisterGnuplotAggregator>();
238  NS_ASSERT(plotAggregator != nullptr);
239  // plot->SetTitle ("");
240  plotAggregator->SetLegend("Time (in seconds)", "Window normalized load (in bps/Hz)");
241  plotAggregator->Add2dDataset("0", "0");
242  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
243 
244  // Setup collector.
245  Ptr<UnitConversionCollector> collector = CreateObject<UnitConversionCollector>();
246  collector->SetName("0");
247  collector->SetConversionType(UnitConversionCollector::TRANSPARENT);
248  collector->TraceConnect("OutputTimeValue",
249  "0",
250  MakeCallback(&MagisterGnuplotAggregator::Write2d, plotAggregator));
251  m_collector = collector->GetObject<DataCollectionObject>();
252 
253  break;
254  }
255 
259  // Setup aggregator.
260  m_aggregator = CreateAggregator("ns3::MagisterGnuplotAggregator",
261  "OutputPath",
262  StringValue(GetOutputPath()),
263  "OutputFileName",
264  StringValue(GetName()));
265  Ptr<MagisterGnuplotAggregator> plotAggregator =
266  m_aggregator->GetObject<MagisterGnuplotAggregator>();
267  NS_ASSERT(plotAggregator != nullptr);
268  // plot->SetTitle ("");
269  plotAggregator->SetLegend("Window normalized load (in bps/Hz)", "Frequency");
270  plotAggregator->Add2dDataset("0", "0");
271  plotAggregator->Set2dDatasetDefaultStyle(Gnuplot2dDataset::LINES);
272 
273  // Setup collector.
274  Ptr<DistributionCollector> collector = CreateObject<DistributionCollector>();
275  collector->SetName("0");
277  {
278  collector->SetOutputType(DistributionCollector::OUTPUT_TYPE_HISTOGRAM);
279  }
281  {
282  collector->SetOutputType(DistributionCollector::OUTPUT_TYPE_PROBABILITY);
283  }
285  {
286  collector->SetOutputType(DistributionCollector::OUTPUT_TYPE_CUMULATIVE);
287  }
288  collector->TraceConnect("Output",
289  "0",
290  MakeCallback(&MagisterGnuplotAggregator::Write2d, plotAggregator));
291  m_collector = collector->GetObject<DataCollectionObject>();
292 
293  break;
294  }
295 
296  default:
297  NS_FATAL_ERROR("SatStatsWindowLoadHelper - Invalid output type");
298  break;
299  }
300 
301  // Setup probes and connect them to the collectors.
302  InstallProbes();
303 
304 } // end of `void DoInstall ();`
305 
306 void
308 {
309  // The method below is supposed to be implemented by the child class.
310  DoInstallProbes();
311 }
312 
313 // RETURN FEEDER LINK ////////////////////////////////////////////////////////
314 
315 NS_OBJECT_ENSURE_REGISTERED(SatStatsRtnFeederWindowLoadHelper);
316 
318  : SatStatsWindowLoadHelper(satHelper)
319 {
320  NS_LOG_FUNCTION(this << satHelper);
321 }
322 
324 {
325  NS_LOG_FUNCTION(this);
326 }
327 
328 TypeId // static
330 {
331  static TypeId tid =
332  TypeId("ns3::SatStatsRtnFeederWindowLoadHelper").SetParent<SatStatsWindowLoadHelper>();
333  return tid;
334 }
335 
336 void
338 {
339  NS_LOG_FUNCTION(this);
340 
341  NodeContainer gws = Singleton<SatTopology>::Get()->GetGwNodes();
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<SatPhy> satPhy = satDev->GetPhy();
351  NS_ASSERT(satPhy != nullptr);
352  Ptr<SatPhyRx> satPhyRx = satPhy->GetPhyRx();
353  NS_ASSERT(satPhyRx != nullptr);
354  ObjectVectorValue carriers;
355  satPhyRx->GetAttribute("RxCarrierList", carriers);
356  NS_LOG_DEBUG(this << " Node ID " << (*it)->GetId() << " device #"
357  << (*itDev)->GetIfIndex() << " has " << carriers.GetN()
358  << " RX carriers");
359 
360  for (ObjectVectorValue::Iterator itCarrier = carriers.Begin();
361  itCarrier != carriers.End();
362  ++itCarrier)
363  {
364  if (DynamicCast<SatPhyRxCarrier>(itCarrier->second)->GetCarrierType() !=
365  SatPhyRxCarrier::CarrierType::RA_ESSA)
366  {
367  continue;
368  }
369  // NS_ASSERT (itCarrier->second->m_channelType == SatEnums::RETURN_FEEDER_CH)
370  if (!itCarrier->second->TraceConnectWithoutContext("WindowLoad",
372  {
373  NS_FATAL_ERROR("Error connecting to WindowLoad trace source"
374  << " of SatPhyRxCarrier"
375  << " at node ID " << (*it)->GetId() << " device #"
376  << (*itDev)->GetIfIndex() << " RX carrier #"
377  << itCarrier->first);
378  }
379 
380  } // end of `for (ObjectVectorValue::Iterator itCarrier = carriers)`
381 
382  } // end of `for (it = gws.Begin(); it != gws.End (); ++it)`
383 
384  } // end of `for (itDev = devs.Begin (); itDev != devs.End (); ++itDev)`
385 
386 } // end of `void DoInstallProbes ();`
387 
388 } // end of namespace ns3
SatNetDevice to be utilized in the UT and GW nodes.
Parent abstract class of all satellite statistics helpers.
static NetDeviceContainer GetGwSatNetDevice(Ptr< Node > gwNode)
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.
OutputType_t GetOutputType() const
std::string GetName() const
virtual std::string GetTimeHeading(std::string dataLabel) const
virtual std::string GetDistributionHeading(std::string dataLabel) const
Produce return feeder window load statistics from a satellite module simulation.
SatStatsRtnFeederWindowLoadHelper(Ptr< const SatHelper > satHelper)
static TypeId GetTypeId()
inherited from ObjectBase base class
Abstract class inherited by SatStatsRtnFeederWindowLoadHelper.
void WindowLoadCallback(double windowLoad)
Receive inputs from trace sources and forward them to the collector.
Ptr< DataCollectionObject > m_aggregator
The aggregator created by this helper.
void InstallProbes()
Set up several probes or other means of listeners and connect them to the collectors.
void DoInstall()
Install the probes, collectors, and aggregators necessary to produce the statistics output.
Callback< void, double > GetTraceSinkCallback() const
virtual void DoInstallProbes()=0
SatStatsWindowLoadHelper(Ptr< const SatHelper > satHelper)
Ptr< DataCollectionObject > m_collector
The collector created by this helper.
static TypeId GetTypeId()
inherited from ObjectBase base class
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.