A Discrete-Event Network Simulator
API
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 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: He Wu <mdzz@u.washington.edu>
18 */
19
20#include "ns3/basic-energy-source-helper.h"
21#include "ns3/basic-energy-source.h"
22#include "ns3/config.h"
23#include "ns3/device-energy-model-container.h"
24#include "ns3/double.h"
25#include "ns3/energy-source-container.h"
26#include "ns3/log.h"
27#include "ns3/node.h"
28#include "ns3/simulator.h"
29#include "ns3/string.h"
30#include "ns3/wifi-radio-energy-model-helper.h"
31#include "ns3/wifi-radio-energy-model.h"
32#include "ns3/yans-wifi-helper.h"
33
34#include <cmath>
35
36using namespace ns3;
37
38NS_LOG_COMPONENT_DEFINE("BasicEnergyModelTestSuite");
39
45{
46 public:
48 virtual ~BasicEnergyUpdateTest();
49
54 bool DoRun();
55
56 private:
64 bool StateSwitchTest(WifiPhyState state);
65
66 private:
67 double m_timeS;
68 double m_tolerance;
69
72};
73
75{
76 m_timeS = 15.5; // idle for 15 seconds before changing state
77 m_tolerance = 1.0e-5; //
78}
79
81{
82}
83
84bool
86{
87 // set types
88 m_energySource.SetTypeId("ns3::BasicEnergySource");
89 m_deviceEnergyModel.SetTypeId("ns3::WifiRadioEnergyModel");
90
91 // run state switch tests
93 {
94 return 1;
95 std::cerr << "Problem with state switch test (WifiPhy idle)." << std::endl;
96 }
98 {
99 return 1;
100 std::cerr << "Problem with state switch test (WifiPhy cca busy)." << std::endl;
101 }
103 {
104 return 1;
105 std::cerr << "Problem with state switch test (WifiPhy tx)." << std::endl;
106 }
108 {
109 return 1;
110 std::cerr << "Problem with state switch test (WifiPhy rx)." << std::endl;
111 }
113 {
114 return 1;
115 std::cerr << "Problem with state switch test (WifiPhy switching)." << std::endl;
116 }
118 {
119 return 1;
120 std::cerr << "Problem with state switch test (WifiPhy sleep)." << std::endl;
121 }
122 return 0;
123}
124
125bool
127{
128 // create node
129 Ptr<Node> node = CreateObject<Node>();
130
131 // create energy source
133 source->SetInitialEnergy(50);
134 // aggregate energy source to node
135 node->AggregateObject(source);
136 source->SetNode(node);
137
138 // create device energy model
140 // set energy source pointer
141 model->SetEnergySource(source);
142 // add device energy model to model list in energy source
143 source->AppendDeviceEnergyModel(model);
144
145 // retrieve device energy model from energy source
146 DeviceEnergyModelContainer models = source->FindDeviceEnergyModels("ns3::WifiRadioEnergyModel");
147 // check list
148 if ((models.GetN() == 0))
149 {
150 std::cerr << "Model list is empty!." << std::endl;
151 return true;
152 }
153 // get pointer
154 Ptr<WifiRadioEnergyModel> devModel = DynamicCast<WifiRadioEnergyModel>(models.Get(0));
155 // check pointer
156 if (!devModel)
157 {
158 std::cerr << "NULL pointer to device model!." << std::endl;
159 return true;
160 }
161
162 /*
163 * The radio will stay IDLE for m_timeS seconds. Then it will switch into a
164 * different state.
165 */
166
167 // schedule change of state
168 Simulator::Schedule(Seconds(m_timeS), &WifiRadioEnergyModel::ChangeState, devModel, state);
169
170 // Calculate remaining energy at simulation stop time
171 Simulator::Schedule(Seconds(m_timeS * 2), &BasicEnergySource::UpdateEnergySource, source);
172
173 double timeDelta = 0.000000001; // 1 nanosecond
174 // run simulation; stop just after last scheduled event
175 Simulator::Stop(Seconds(m_timeS * 2 + timeDelta));
176 Simulator::Run();
177
178 // energy = current * voltage * time
179
180 // calculate idle power consumption
181 double estRemainingEnergy = source->GetInitialEnergy();
182 double voltage = source->GetSupplyVoltage();
183 estRemainingEnergy -= devModel->GetIdleCurrentA() * voltage * m_timeS;
184
185 // calculate new state power consumption
186 double current = 0.0;
187 switch (state)
188 {
190 current = devModel->GetIdleCurrentA();
191 break;
193 current = devModel->GetCcaBusyCurrentA();
194 break;
195 case WifiPhyState::TX:
196 current = devModel->GetTxCurrentA();
197 break;
198 case WifiPhyState::RX:
199 current = devModel->GetRxCurrentA();
200 break;
202 current = devModel->GetSwitchingCurrentA();
203 break;
205 current = devModel->GetSleepCurrentA();
206 break;
208 current = 0;
209 break;
210 default:
211 NS_FATAL_ERROR("Undefined radio state: " << state);
212 break;
213 }
214 estRemainingEnergy -= current * voltage * m_timeS;
215 estRemainingEnergy = std::max(0.0, estRemainingEnergy);
216
217 // obtain remaining energy from source
218 double remainingEnergy = source->GetRemainingEnergy();
219 NS_LOG_DEBUG("Remaining energy is " << remainingEnergy);
220 NS_LOG_DEBUG("Estimated remaining energy is " << estRemainingEnergy);
221 NS_LOG_DEBUG("Difference is " << estRemainingEnergy - remainingEnergy);
222
223 // check remaining energy
224 if ((remainingEnergy > (estRemainingEnergy + m_tolerance)) ||
225 (remainingEnergy < (estRemainingEnergy - m_tolerance)))
226 {
227 std::cerr << "Incorrect remaining energy!" << std::endl;
228 return true;
229 }
230
231 // obtain radio state
232 WifiPhyState endState = devModel->GetCurrentState();
233 NS_LOG_DEBUG("Radio state is " << endState);
234 // check end state
235 if (endState != state)
236 {
237 std::cerr << "Incorrect end state!" << std::endl;
238 return true;
239 }
240 Simulator::Destroy();
241
242 return false; // no error
243}
244
245// -------------------------------------------------------------------------- //
246
252{
253 public:
256
261 bool DoRun();
262
263 private:
267 void DepletionHandler();
268
276 bool DepletionTestCase(double simTimeS, double updateIntervalS);
277
278 private:
281 double m_simTimeS;
282 double m_timeStepS;
284};
285
287{
288 m_numOfNodes = 10;
289 m_callbackCount = 0;
290 m_simTimeS = 4.5;
291 m_timeStepS = 0.5;
292 m_updateIntervalS = 1.5;
293}
294
296{
297}
298
299bool
301{
302 /*
303 * Run simulation with different simulation time and update interval.
304 */
305 uint8_t ret = 0;
306
307 for (double simTimeS = 0.0; simTimeS <= m_simTimeS; simTimeS += m_timeStepS)
308 {
309 for (double updateIntervalS = 0.5; updateIntervalS <= m_updateIntervalS;
310 updateIntervalS += m_timeStepS)
311 {
312 if (DepletionTestCase(simTimeS, updateIntervalS))
313 {
314 ret = 1;
315 std::cerr << "Depletion test case problem." << std::endl;
316 }
317 // reset callback count
318 m_callbackCount = 0;
319 }
320 }
321 return ret;
322}
323
324void
326{
328}
329
330bool
331BasicEnergyDepletionTest::DepletionTestCase(double simTimeS, double updateIntervalS)
332{
333 // create node
336
337 std::string phyMode("DsssRate1Mbps");
338
339 // disable fragmentation for frames below 2200 bytes
340 Config::SetDefault("ns3::WifiRemoteStationManager::FragmentationThreshold",
341 StringValue("2200"));
342 // turn off RTS/CTS for frames below 2200 bytes
343 Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue("2200"));
344 // Fix non-unicast data rate to be the same as that of unicast
345 Config::SetDefault("ns3::WifiRemoteStationManager::NonUnicastMode", StringValue(phyMode));
346
347 // install YansWifiPhy
349 wifi.SetStandard(WIFI_STANDARD_80211b);
350
351 YansWifiPhyHelper wifiPhy;
352 /*
353 * This is one parameter that matters when using FixedRssLossModel, set it to
354 * zero; otherwise, gain will be added.
355 */
356 wifiPhy.Set("RxGain", DoubleValue(0));
357 // ns-3 supports RadioTap and Prism tracing extensions for 802.11b
358 wifiPhy.SetPcapDataLinkType(WifiPhyHelper::DLT_IEEE802_11_RADIO);
359
360 YansWifiChannelHelper wifiChannel;
361 wifiChannel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel");
362 wifiPhy.SetChannel(wifiChannel.Create());
363
364 // Add a MAC and disable rate control
365 WifiMacHelper wifiMac;
366 wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager",
367 "DataMode",
368 StringValue(phyMode),
369 "ControlMode",
370 StringValue(phyMode));
371 // Set it to ad-hoc mode
372 wifiMac.SetType("ns3::AdhocWifiMac");
373 NetDeviceContainer devices = wifi.Install(wifiPhy, wifiMac, c);
374
375 /*
376 * Create and install energy source and a single basic radio energy model on
377 * the node using helpers.
378 */
379 // source helper
380 BasicEnergySourceHelper basicSourceHelper;
381 // set energy to 0 so that we deplete energy at the beginning of simulation
382 basicSourceHelper.Set("BasicEnergySourceInitialEnergyJ", DoubleValue(0.0));
383 // set update interval
384 basicSourceHelper.Set("PeriodicEnergyUpdateInterval", TimeValue(Seconds(updateIntervalS)));
385 // install source
386 EnergySourceContainer sources = basicSourceHelper.Install(c);
387
388 // device energy model helper
389 WifiRadioEnergyModelHelper radioEnergyHelper;
390 // set energy depletion callback
393 radioEnergyHelper.SetDepletionCallback(callback);
394 // install on node
395 DeviceEnergyModelContainer deviceModels = radioEnergyHelper.Install(devices, sources);
396
397 // run simulation
398 Simulator::Stop(Seconds(simTimeS));
399 Simulator::Run();
400 Simulator::Destroy();
401
402 NS_LOG_DEBUG("Simulation time = " << simTimeS << "s");
403 NS_LOG_DEBUG("Update interval = " << updateIntervalS << "s");
404 NS_LOG_DEBUG("Expected callback count is " << m_numOfNodes);
405 NS_LOG_DEBUG("Actual callback count is " << m_callbackCount);
406
407 // check result, call back should only be invoked once
409 {
410 std::cerr << "Not all callbacks are invoked!" << std::endl;
411 return true;
412 }
413
414 return false;
415}
416
417// -------------------------------------------------------------------------- //
418
419int
420main(int argc, char** argv)
421{
422 BasicEnergyUpdateTest testEnergyUpdate;
423 if (testEnergyUpdate.DoRun())
424 {
425 return 1;
426 }
427
428 BasicEnergyDepletionTest testEnergyDepletion;
429 if (testEnergyDepletion.DoRun())
430 {
431 return 1;
432 }
433
434 return 0;
435}
#define max(a, b)
Definition: 80211b.c:43
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
BasicEnergySource decreases/increases remaining energy stored in itself in linearly.
double GetSupplyVoltage() const override
double GetRemainingEnergy() override
double GetInitialEnergy() const override
void SetInitialEnergy(double initialEnergyJ)
Holds a vector of ns3::DeviceEnergyModel pointers.
uint32_t GetN() const
Get the number of Ptr<DeviceEnergyModel> stored in this container.
Ptr< DeviceEnergyModel > Get(uint32_t i) const
Get the i-th Ptr<DeviceEnergyModel> stored in this container.
DeviceEnergyModelContainer Install(Ptr< NetDevice > device, Ptr< EnergySource > source) const
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
Holds a vector of ns3::EnergySource pointers.
EnergySourceContainer Install(Ptr< Node > node) const
void AppendDeviceEnergyModel(Ptr< DeviceEnergyModel > deviceEnergyModelPtr)
DeviceEnergyModelContainer FindDeviceEnergyModels(TypeId tid)
void SetNode(Ptr< Node > node)
Sets pointer to node containing this EnergySource.
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.
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:259
Hold variables of type string.
Definition: string.h:42
AttributeValue implementation for Time.
Definition: nstime.h:1425
helps to create WifiNetDevice objects
Definition: wifi-helper.h:325
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.
Definition: wifi-helper.cc:543
void Set(std::string name, const AttributeValue &v)
Definition: wifi-helper.cc:163
Assign WifiRadioEnergyModel to wifi devices.
void SetDepletionCallback(WifiRadioEnergyModel::WifiRadioEnergyDepletionCallback callback)
A WiFi radio energy model.
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)
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:891
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:160
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
@ WIFI_STANDARD_80211b
devices
Definition: first.py:35
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:691
wifi
Definition: third.py:88
WifiPhyState
The state of the PHY layer.
@ CCA_BUSY
The PHY layer has sense the medium busy through the CCA mechanism.
@ SWITCHING
The PHY layer is switching to other channel.
@ RX
The PHY layer is receiving a packet.
@ TX
The PHY layer is sending a packet.
@ OFF
The PHY layer is switched off.
@ SLEEP
The PHY layer is sleeping.
@ IDLE
The PHY layer is IDLE.