A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
spectrum-ideal-phy-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011 CTTC
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Nicola Baldo <nbaldo@cttc.es>
7 */
8
9#include <ns3/adhoc-aloha-noack-ideal-phy-helper.h>
10#include <ns3/config.h>
11#include <ns3/data-rate.h>
12#include <ns3/friis-spectrum-propagation-loss.h>
13#include <ns3/ism-spectrum-value-helper.h>
14#include <ns3/log.h>
15#include <ns3/math.h>
16#include <ns3/mobility-helper.h>
17#include <ns3/object.h>
18#include <ns3/packet-socket-address.h>
19#include <ns3/packet-socket-client.h>
20#include <ns3/packet-socket-helper.h>
21#include <ns3/packet.h>
22#include <ns3/propagation-delay-model.h>
23#include <ns3/ptr.h>
24#include <ns3/simulator.h>
25#include <ns3/single-model-spectrum-channel.h>
26#include <ns3/spectrum-analyzer.h>
27#include <ns3/spectrum-error-model.h>
28#include <ns3/spectrum-helper.h>
29#include <ns3/spectrum-interference.h>
30#include <ns3/spectrum-model-300kHz-300GHz-log.h>
31#include <ns3/spectrum-model-ism2400MHz-res1MHz.h>
32#include <ns3/string.h>
33#include <ns3/test.h>
34#include <ns3/uinteger.h>
35#include <ns3/waveform-generator.h>
36
37#include <iomanip>
38#include <iostream>
39#include <string>
40
41using namespace ns3;
42
43NS_LOG_COMPONENT_DEFINE("SpectrumIdealPhyTest");
44
45static uint64_t g_rxBytes;
46static double g_bandwidth = 20e6; // Hz
47
48void
49PhyRxEndOkTrace(std::string context, Ptr<const Packet> p)
50{
51 g_rxBytes += p->GetSize();
52}
53
54/**
55 * \ingroup spectrum-tests
56 *
57 * \brief Ideal Spectrum PHY Test
58 */
60{
61 public:
62 /**
63 * Constructor
64 * \param snrLinear SNR (linear)
65 * \param phyRate PHY rate (bps)
66 * \param rateIsAchievable Check if the rate is achievable
67 * \param channelType Channel type
68 */
69 SpectrumIdealPhyTestCase(double snrLinear,
70 uint64_t phyRate,
71 bool rateIsAchievable,
72 std::string channelType);
74
75 private:
76 void DoRun() override;
77 /**
78 * Get the test name
79 * \param channelType Channel type
80 * \param snrLinear SNR (linear)
81 * \param phyRate PHY rate (bps)
82 * \return the test name
83 */
84 static std::string Name(std::string channelType, double snrLinear, uint64_t phyRate);
85
86 double m_snrLinear; //!< SNR (linear)
87 uint64_t m_phyRate; //!< PHY rate (bps)
88 bool m_rateIsAchievable; //!< Check if the rate is achievable
89 std::string m_channelType; //!< Channel type
90};
91
92std::string
93SpectrumIdealPhyTestCase::Name(std::string channelType, double snrLinear, uint64_t phyRate)
94{
95 std::ostringstream oss;
96 oss << channelType << " snr = " << snrLinear << " (linear), "
97 << " phyRate = " << phyRate << " bps";
98 return oss.str();
99}
100
102 uint64_t phyRate,
103 bool rateIsAchievable,
104 std::string channelType)
105 : TestCase(Name(channelType, snrLinear, phyRate)),
106 m_snrLinear(snrLinear),
107 m_phyRate(phyRate),
108 m_rateIsAchievable(rateIsAchievable),
109 m_channelType(channelType)
110{
111}
112
116
117void
119{
121 double txPowerW = 0.1;
122 // for the noise, we use the Power Spectral Density of thermal noise
123 // at room temperature. The value of the PSD will be constant over the band of interest.
124 const double k = 1.381e-23; // Boltzmann's constant
125 const double T = 290; // temperature in Kelvin
126 double noisePsdValue = k * T; // W/Hz
127 double lossLinear = (txPowerW) / (m_snrLinear * noisePsdValue * g_bandwidth);
128 double lossDb = 10 * std::log10(lossLinear);
129 uint64_t phyRate = m_phyRate; // bps
130 uint32_t pktSize = 50; // bytes
131
132 uint32_t numPkts = 200; // desired number of packets in the
133 // test. Directly related with the accuracy
134 // of the measurement.
135
136 double testDuration = (numPkts * pktSize * 8.0) / phyRate;
137 NS_LOG_INFO("test duration = " << std::fixed << testDuration);
138
140 c.Create(2);
141
142 MobilityHelper mobility;
144 positionAlloc->Add(Vector(0.0, 0.0, 0.0));
145 positionAlloc->Add(Vector(5.0, 0.0, 0.0));
146 mobility.SetPositionAllocator(positionAlloc);
147 mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
148
149 mobility.Install(c);
150
151 SpectrumChannelHelper channelHelper;
152 channelHelper.SetChannel(m_channelType);
153 channelHelper.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel");
155 propLoss->SetLoss(c.Get(0)->GetObject<MobilityModel>(),
156 c.Get(1)->GetObject<MobilityModel>(),
157 lossDb,
158 true);
159 channelHelper.AddPropagationLoss(propLoss);
160 Ptr<SpectrumChannel> channel = channelHelper.Create();
161
163
164 uint32_t channelNumber = 1;
165 Ptr<SpectrumValue> txPsd = sf.CreateTxPowerSpectralDensity(txPowerW, channelNumber);
166
167 Ptr<SpectrumValue> noisePsd = sf.CreateConstant(noisePsdValue);
168
170 deviceHelper.SetChannel(channel);
171 deviceHelper.SetTxPowerSpectralDensity(txPsd);
172 deviceHelper.SetNoisePowerSpectralDensity(noisePsd);
173 deviceHelper.SetPhyAttribute("Rate", DataRateValue(DataRate(phyRate)));
174 NetDeviceContainer devices = deviceHelper.Install(c);
175
176 PacketSocketHelper packetSocket;
177 packetSocket.Install(c);
178
179 PacketSocketAddress socket;
180 socket.SetSingleDevice(devices.Get(0)->GetIfIndex());
181 socket.SetPhysicalAddress(devices.Get(1)->GetAddress());
182 socket.SetProtocol(1);
183
185 client->SetRemote(socket);
186 client->SetAttribute("Interval",
187 TimeValue(Seconds(double(pktSize * 8) / (1.2 * double(phyRate)))));
188 client->SetAttribute("PacketSize", UintegerValue(pktSize));
189 client->SetAttribute("MaxPackets", UintegerValue(0));
190 client->SetStartTime(Seconds(0.0));
191 client->SetStopTime(Seconds(testDuration));
192 c.Get(0)->AddApplication(client);
193
194 Config::Connect("/NodeList/*/DeviceList/*/Phy/RxEndOk", MakeCallback(&PhyRxEndOkTrace));
195
196 g_rxBytes = 0;
197 Simulator::Stop(Seconds(testDuration + 0.000000001));
199 double throughputBps = (g_rxBytes * 8.0) / testDuration;
200
201 std::clog.unsetf(std::ios_base::floatfield);
202
204 {
205 NS_TEST_ASSERT_MSG_EQ_TOL(throughputBps,
206 m_phyRate,
207 m_phyRate * 0.01,
208 "throughput does not match PHY rate");
209 }
210 else
211 {
212 NS_TEST_ASSERT_MSG_EQ(throughputBps,
213 0.0,
214 "PHY rate is not achievable but throughput is non-zero");
215 }
216
218}
219
220/**
221 * \ingroup spectrum-tests
222 *
223 * \brief Ideal Spectrum PHY TestSuite
224 */
226{
227 public:
229};
230
232 : TestSuite("spectrum-ideal-phy", Type::SYSTEM)
233{
234 NS_LOG_INFO("creating SpectrumIdealPhyTestSuite");
235
236 for (double snr = 0.01; snr <= 10; snr *= 2)
237 {
238 double achievableRate = g_bandwidth * log2(1 + snr);
240 static_cast<uint64_t>(achievableRate * 0.1),
241 true,
242 "ns3::SingleModelSpectrumChannel"),
243 TestCase::Duration::QUICK);
245 static_cast<uint64_t>(achievableRate * 0.5),
246 true,
247 "ns3::SingleModelSpectrumChannel"),
248 TestCase::Duration::QUICK);
250 static_cast<uint64_t>(achievableRate * 0.95),
251 true,
252 "ns3::SingleModelSpectrumChannel"),
253 TestCase::Duration::QUICK);
255 static_cast<uint64_t>(achievableRate * 1.05),
256 false,
257 "ns3::SingleModelSpectrumChannel"),
258 TestCase::Duration::QUICK);
260 static_cast<uint64_t>(achievableRate * 2),
261 false,
262 "ns3::SingleModelSpectrumChannel"),
263 TestCase::Duration::QUICK);
265 static_cast<uint64_t>(achievableRate * 4),
266 false,
267 "ns3::SingleModelSpectrumChannel"),
268 TestCase::Duration::QUICK);
269 }
270 for (double snr = 0.01; snr <= 10; snr *= 10)
271 {
272 double achievableRate = g_bandwidth * log2(1 + snr);
274 static_cast<uint64_t>(achievableRate * 0.1),
275 true,
276 "ns3::MultiModelSpectrumChannel"),
277 TestCase::Duration::QUICK);
279 static_cast<uint64_t>(achievableRate * 0.5),
280 true,
281 "ns3::MultiModelSpectrumChannel"),
282 TestCase::Duration::QUICK);
284 static_cast<uint64_t>(achievableRate * 0.95),
285 true,
286 "ns3::MultiModelSpectrumChannel"),
287 TestCase::Duration::QUICK);
289 static_cast<uint64_t>(achievableRate * 1.05),
290 false,
291 "ns3::MultiModelSpectrumChannel"),
292 TestCase::Duration::QUICK);
294 static_cast<uint64_t>(achievableRate * 2),
295 false,
296 "ns3::MultiModelSpectrumChannel"),
297 TestCase::Duration::QUICK);
299 static_cast<uint64_t>(achievableRate * 4),
300 false,
301 "ns3::MultiModelSpectrumChannel"),
302 TestCase::Duration::QUICK);
303 }
304}
305
306/// Static variable for test initialization
static std::string Name(std::string channelType, double snrLinear, uint64_t phyRate)
Get the test name.
bool m_rateIsAchievable
Check if the rate is achievable.
uint64_t m_phyRate
PHY rate (bps)
void DoRun() override
Implementation to actually run this TestCase.
std::string m_channelType
Channel type.
SpectrumIdealPhyTestCase(double snrLinear, uint64_t phyRate, bool rateIsAchievable, std::string channelType)
Constructor.
Ideal Spectrum PHY TestSuite.
void SetPhyAttribute(std::string name, const AttributeValue &v)
void SetTxPowerSpectralDensity(Ptr< SpectrumValue > txPsd)
void SetNoisePowerSpectralDensity(Ptr< SpectrumValue > noisePsd)
void SetChannel(Ptr< SpectrumChannel > channel)
set the SpectrumChannel that will be used by SpectrumPhy instances created by this helper
NetDeviceContainer Install(NodeContainer c) const
Class for representing data rates.
Definition data-rate.h:78
Helper class used to assign positions and mobility models to nodes.
Keep track of the current position and velocity of an object.
holds a vector of ns3::NetDevice pointers
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition node.cc:153
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition object.h:511
an address for a packet socket
void SetProtocol(uint16_t protocol)
Set the protocol.
void SetPhysicalAddress(const Address address)
Set the destination address.
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
Give ns3::PacketSocket powers to ns3::Node.
void Install(Ptr< Node > node) const
Aggregate an instance of a ns3::PacketSocketFactory onto the provided node.
Smart pointer class similar to boost::intrusive_ptr.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
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
Setup a SpectrumChannel.
Ptr< SpectrumChannel > Create() const
void AddPropagationLoss(std::string name, Ts &&... args)
void SetPropagationDelay(std::string name, Ts &&... args)
void SetChannel(std::string type, Ts &&... args)
Implements Wifi SpectrumValue for the 2.4 GHz ISM band only, with a 5 MHz spectrum resolution.
virtual Ptr< SpectrumValue > CreateConstant(double psd)
Creates a SpectrumValue instance with a constant value for all frequencies.
virtual Ptr< SpectrumValue > CreateTxPowerSpectralDensity(double txPower, uint8_t channel)
Creates a SpectrumValue instance that represents the TX Power Spectral Density of a wifi device corre...
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
Type
Type of test.
Definition test.h:1274
Hold an unsigned integer type.
Definition uinteger.h:34
void Connect(std::string path, const CallbackBase &cb)
Definition config.cc:967
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition test.h:134
#define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report and...
Definition test.h:327
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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
void PhyRxEndOkTrace(std::string context, Ptr< const Packet > p)
static SpectrumIdealPhyTestSuite g_spectrumIdealPhyTestSuite
Static variable for test initialization.
static uint64_t g_rxBytes
static double g_bandwidth
static std::string Name(std::string str, uint32_t totalStreamSize, uint32_t sourceWriteSize, uint32_t serverReadSize, uint32_t serverWriteSize, uint32_t sourceReadSize, bool useIpv6)
Definition tcp-test.cc:155
uint32_t pktSize
packet size used for the simulation (in bytes)