A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
basic-energy-model-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010 Network Security Lab, University of Washington, Seattle.
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: He Wu <mdzz@u.washington.edu>
7 */
8
9#include "ns3/basic-energy-source-helper.h"
10#include "ns3/basic-energy-source.h"
11#include "ns3/config.h"
12#include "ns3/device-energy-model-container.h"
13#include "ns3/double.h"
14#include "ns3/energy-source-container.h"
15#include "ns3/log.h"
16#include "ns3/node.h"
17#include "ns3/simulator.h"
18#include "ns3/string.h"
19#include "ns3/wifi-radio-energy-model-helper.h"
20#include "ns3/wifi-radio-energy-model.h"
21#include "ns3/yans-wifi-helper.h"
22
23#include <cmath>
24
25using namespace ns3;
26using namespace ns3::energy;
27
28NS_LOG_COMPONENT_DEFINE("BasicEnergyModelTestSuite");
29
30/**
31 * Test case of update remaining energy for BasicEnergySource and
32 * WifiRadioEnergyModel.
33 */
35{
36 public:
38 virtual ~BasicEnergyUpdateTest();
39
40 /**
41 * Performs some tests involving state updates and the relative energy consumption
42 * \return true is some error happened.
43 */
44 bool DoRun();
45
46 private:
47 /**
48 * \param state Radio state to switch to.
49 * \return False if no error occurs.
50 *
51 * Runs simulation for a while, check if final state & remaining energy is
52 * correctly updated.
53 */
54 bool StateSwitchTest(WifiPhyState state);
55
56 private:
57 double m_timeS; //!< Time in seconds
58 double m_tolerance; //!< Tolerance for power estimation
59
60 ObjectFactory m_energySource; //!< Energy source factory
61 ObjectFactory m_deviceEnergyModel; //!< Device energy model factory
62};
63
65{
66 m_timeS = 15.5; // idle for 15 seconds before changing state
67 m_tolerance = 1.0e-5; //
68}
69
73
74bool
76{
77 // set types
78 m_energySource.SetTypeId("ns3::BasicEnergySource");
79 m_deviceEnergyModel.SetTypeId("ns3::WifiRadioEnergyModel");
80
81 // run state switch tests
82 if (StateSwitchTest(WifiPhyState::IDLE))
83 {
84 return true;
85 std::cerr << "Problem with state switch test (WifiPhy idle)." << std::endl;
86 }
87 if (StateSwitchTest(WifiPhyState::CCA_BUSY))
88 {
89 return true;
90 std::cerr << "Problem with state switch test (WifiPhy cca busy)." << std::endl;
91 }
92 if (StateSwitchTest(WifiPhyState::TX))
93 {
94 return true;
95 std::cerr << "Problem with state switch test (WifiPhy tx)." << std::endl;
96 }
97 if (StateSwitchTest(WifiPhyState::RX))
98 {
99 return true;
100 std::cerr << "Problem with state switch test (WifiPhy rx)." << std::endl;
101 }
102 if (StateSwitchTest(WifiPhyState::SWITCHING))
103 {
104 return true;
105 std::cerr << "Problem with state switch test (WifiPhy switching)." << std::endl;
106 }
107 if (StateSwitchTest(WifiPhyState::SLEEP))
108 {
109 return true;
110 std::cerr << "Problem with state switch test (WifiPhy sleep)." << std::endl;
111 }
112 return false;
113}
114
115bool
117{
118 // create node
120
121 // create energy source
123 source->SetInitialEnergy(50);
124 // aggregate energy source to node
125 node->AggregateObject(source);
126 source->SetNode(node);
127
128 // create device energy model
130 // set energy source pointer
131 model->SetEnergySource(source);
132 // add device energy model to model list in energy source
133 source->AppendDeviceEnergyModel(model);
134
135 // retrieve device energy model from energy source
136 DeviceEnergyModelContainer models = source->FindDeviceEnergyModels("ns3::WifiRadioEnergyModel");
137 // check list
138 if (models.GetN() == 0)
139 {
140 std::cerr << "Model list is empty!." << std::endl;
141 return true;
142 }
143 // get pointer
145 // check pointer
146 if (!devModel)
147 {
148 std::cerr << "NULL pointer to device model!." << std::endl;
149 return true;
150 }
151
152 /*
153 * The radio will stay IDLE for m_timeS seconds. Then it will switch into a
154 * different state.
155 */
156
157 // schedule change of state
160 devModel,
161 static_cast<int>(state));
162
163 // Calculate remaining energy at simulation stop time
165
166 double timeDelta = 0.000000001; // 1 nanosecond
167 // run simulation; stop just after last scheduled event
168 Simulator::Stop(Seconds(m_timeS * 2 + timeDelta));
170
171 // energy = current * voltage * time
172
173 // calculate idle power consumption
174 double estRemainingEnergy = source->GetInitialEnergy();
175 double voltage = source->GetSupplyVoltage();
176 estRemainingEnergy -= devModel->GetIdleCurrentA() * voltage * m_timeS;
177
178 // calculate new state power consumption
179 double current = 0.0;
180 switch (state)
181 {
182 case WifiPhyState::IDLE:
183 current = devModel->GetIdleCurrentA();
184 break;
185 case WifiPhyState::CCA_BUSY:
186 current = devModel->GetCcaBusyCurrentA();
187 break;
188 case WifiPhyState::TX:
189 current = devModel->GetTxCurrentA();
190 break;
191 case WifiPhyState::RX:
192 current = devModel->GetRxCurrentA();
193 break;
194 case WifiPhyState::SWITCHING:
195 current = devModel->GetSwitchingCurrentA();
196 break;
197 case WifiPhyState::SLEEP:
198 current = devModel->GetSleepCurrentA();
199 break;
200 case WifiPhyState::OFF:
201 current = 0;
202 break;
203 default:
204 NS_FATAL_ERROR("Undefined radio state: " << state);
205 break;
206 }
207 estRemainingEnergy -= current * voltage * m_timeS;
208 estRemainingEnergy = std::max(0.0, estRemainingEnergy);
209
210 // obtain remaining energy from source
211 double remainingEnergy = source->GetRemainingEnergy();
212 NS_LOG_DEBUG("Remaining energy is " << remainingEnergy);
213 NS_LOG_DEBUG("Estimated remaining energy is " << estRemainingEnergy);
214 NS_LOG_DEBUG("Difference is " << estRemainingEnergy - remainingEnergy);
215
216 // check remaining energy
217 if ((remainingEnergy > (estRemainingEnergy + m_tolerance)) ||
218 (remainingEnergy < (estRemainingEnergy - m_tolerance)))
219 {
220 std::cerr << "Incorrect remaining energy!" << std::endl;
221 return true;
222 }
223
224 // obtain radio state
225 WifiPhyState endState = devModel->GetCurrentState();
226 NS_LOG_DEBUG("Radio state is " << endState);
227 // check end state
228 if (endState != state)
229 {
230 std::cerr << "Incorrect end state!" << std::endl;
231 return true;
232 }
234
235 return false; // no error
236}
237
238// -------------------------------------------------------------------------- //
239
240/**
241 * Test case of energy depletion handling for BasicEnergySource and
242 * WifiRadioEnergyModel.
243 */
245{
246 public:
249
250 /**
251 * Performs some tests involving energy depletion
252 * \return true is some error happened.
253 */
254 bool DoRun();
255
256 private:
257 /**
258 * Callback invoked when energy is drained from source.
259 */
260 void DepletionHandler();
261
262 /**
263 * \param simTimeS Simulation time, in seconds.
264 * \param updateIntervalS Device model update interval, in seconds.
265 * \return False if all is good.
266 *
267 * Runs simulation with specified simulation time and update interval.
268 */
269 bool DepletionTestCase(double simTimeS, double updateIntervalS);
270
271 private:
272 int m_numOfNodes; //!< number of nodes in simulation
273 int m_callbackCount; //!< counter for # of callbacks invoked
274 double m_simTimeS; //!< maximum simulation time, in seconds
275 double m_timeStepS; //!< simulation time step size, in seconds
276 double m_updateIntervalS; //!< update interval of each device model
277};
278
287
291
292bool
294{
295 /*
296 * Run simulation with different simulation time and update interval.
297 */
298 bool ret = false;
299
300 for (double simTimeS = 0.0; simTimeS <= m_simTimeS; simTimeS += m_timeStepS)
301 {
302 for (double updateIntervalS = 0.5; updateIntervalS <= m_updateIntervalS;
303 updateIntervalS += m_timeStepS)
304 {
305 if (DepletionTestCase(simTimeS, updateIntervalS))
306 {
307 ret = true;
308 std::cerr << "Depletion test case problem." << std::endl;
309 }
310 // reset callback count
311 m_callbackCount = 0;
312 }
313 }
314 return ret;
315}
316
317void
322
323bool
324BasicEnergyDepletionTest::DepletionTestCase(double simTimeS, double updateIntervalS)
325{
326 // create node
329
330 std::string phyMode("DsssRate1Mbps");
331
332 // disable fragmentation for frames below 2200 bytes
333 Config::SetDefault("ns3::WifiRemoteStationManager::FragmentationThreshold",
334 StringValue("2200"));
335 // turn off RTS/CTS for frames below 2200 bytes
336 Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue("2200"));
337 // Fix non-unicast data rate to be the same as that of unicast
338 Config::SetDefault("ns3::WifiRemoteStationManager::NonUnicastMode", StringValue(phyMode));
339
340 // install YansWifiPhy
341 WifiHelper wifi;
342 wifi.SetStandard(WIFI_STANDARD_80211b);
343
344 YansWifiPhyHelper wifiPhy;
345 /*
346 * This is one parameter that matters when using FixedRssLossModel, set it to
347 * zero; otherwise, gain will be added.
348 */
349 wifiPhy.Set("RxGain", DoubleValue(0));
350 // ns-3 supports RadioTap and Prism tracing extensions for 802.11b
352
353 YansWifiChannelHelper wifiChannel;
354 wifiChannel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel");
355 wifiPhy.SetChannel(wifiChannel.Create());
356
357 // Add a MAC and disable rate control
358 WifiMacHelper wifiMac;
359 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
360 "DataMode",
361 StringValue(phyMode),
362 "ControlMode",
363 StringValue(phyMode));
364 // Set it to ad-hoc mode
365 wifiMac.SetType("ns3::AdhocWifiMac");
366 NetDeviceContainer devices = wifi.Install(wifiPhy, wifiMac, c);
367
368 /*
369 * Create and install energy source and a single basic radio energy model on
370 * the node using helpers.
371 */
372 // source helper
373 BasicEnergySourceHelper basicSourceHelper;
374 // set energy to 0 so that we deplete energy at the beginning of simulation
375 basicSourceHelper.Set("BasicEnergySourceInitialEnergyJ", DoubleValue(0.0));
376 // set update interval
377 basicSourceHelper.Set("PeriodicEnergyUpdateInterval", TimeValue(Seconds(updateIntervalS)));
378 // install source
379 EnergySourceContainer sources = basicSourceHelper.Install(c);
380
381 // device energy model helper
382 WifiRadioEnergyModelHelper radioEnergyHelper;
383 // set energy depletion callback
386 radioEnergyHelper.SetDepletionCallback(callback);
387 // install on node
388 DeviceEnergyModelContainer deviceModels = radioEnergyHelper.Install(devices, sources);
389
390 // run simulation
391 Simulator::Stop(Seconds(simTimeS));
394
395 NS_LOG_DEBUG("Simulation time = " << simTimeS << "s");
396 NS_LOG_DEBUG("Update interval = " << updateIntervalS << "s");
397 NS_LOG_DEBUG("Expected callback count is " << m_numOfNodes);
398 NS_LOG_DEBUG("Actual callback count is " << m_callbackCount);
399
400 // check result, call back should only be invoked once
402 {
403 std::cerr << "Not all callbacks are invoked!" << std::endl;
404 return true;
405 }
406
407 return false;
408}
409
410// -------------------------------------------------------------------------- //
411
412int
413main(int argc, char** argv)
414{
415 BasicEnergyUpdateTest testEnergyUpdate;
416 if (testEnergyUpdate.DoRun())
417 {
418 return 1;
419 }
420
421 BasicEnergyDepletionTest testEnergyDepletion;
422 if (testEnergyDepletion.DoRun())
423 {
424 return 1;
425 }
426
427 return 0;
428}
Test case of energy depletion handling for BasicEnergySource and WifiRadioEnergyModel.
double m_updateIntervalS
update interval of each device model
double m_simTimeS
maximum simulation time, in seconds
double m_timeStepS
simulation time step size, in seconds
int m_numOfNodes
number of nodes in simulation
bool DepletionTestCase(double simTimeS, double updateIntervalS)
bool DoRun()
Performs some tests involving energy depletion.
void DepletionHandler()
Callback invoked when energy is drained from source.
int m_callbackCount
counter for # of callbacks invoked
Test case of update remaining energy for BasicEnergySource and WifiRadioEnergyModel.
double m_timeS
Time in seconds.
ObjectFactory m_energySource
Energy source factory.
ObjectFactory m_deviceEnergyModel
Device energy model factory.
bool StateSwitchTest(WifiPhyState state)
bool DoRun()
Performs some tests involving state updates and the relative energy consumption.
double m_tolerance
Tolerance for power estimation.
Creates a BasicEnergySource object.
void Set(std::string name, const AttributeValue &v) override
energy::DeviceEnergyModelContainer Install(Ptr< NetDevice > device, Ptr< energy::EnergySource > source) const
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
energy::EnergySourceContainer Install(Ptr< Node > node) const
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.
Instantiate subclasses of ns3::Object.
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
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 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
Hold variables of type string.
Definition string.h:45
helps to create WifiNetDevice objects
create MAC layers for a ns3::WifiNetDevice.
void SetType(std::string type, Args &&... args)
void SetPcapDataLinkType(SupportedPcapDataLinkTypes dlt)
Set the data link type of PCAP traces to be used.
void Set(std::string name, const AttributeValue &v)
@ DLT_IEEE802_11_RADIO
Include Radiotap link layer information.
Assign WifiRadioEnergyModel to wifi devices.
void SetDepletionCallback(WifiRadioEnergyModel::WifiRadioEnergyDepletionCallback callback)
A WiFi radio energy model.
void ChangeState(int newState) override
Changes state of the WifiRadioEnergyMode.
manage and create wifi channel objects for the YANS model.
void SetPropagationDelay(std::string name, Ts &&... args)
Ptr< YansWifiChannel > Create() const
Make it easy to create and manage PHY objects for the YANS model.
void SetChannel(Ptr< YansWifiChannel > channel)
BasicEnergySource decreases/increases remaining energy stored in itself in linearly.
void UpdateEnergySource() override
Implements UpdateEnergySource.
Holds a vector of ns3::DeviceEnergyModel pointers.
Ptr< DeviceEnergyModel > Get(uint32_t i) const
Get the i-th Ptr<DeviceEnergyModel> stored in this container.
uint32_t GetN() const
Get the number of Ptr<DeviceEnergyModel> stored in this container.
Holds a vector of ns3::EnergySource pointers.
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:883
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#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
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
@ WIFI_STANDARD_80211b
Every class exported by the ns3 library is enclosed in the ns3 namespace.
WifiPhyState
The state of the PHY layer.
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
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580