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 
36 using namespace ns3;
37 
38 NS_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 
84 bool
86 {
87  // set types
88  m_energySource.SetTypeId("ns3::BasicEnergySource");
89  m_deviceEnergyModel.SetTypeId("ns3::WifiRadioEnergyModel");
90 
91  // run state switch tests
92  if (StateSwitchTest(WifiPhyState::IDLE))
93  {
94  return true;
95  std::cerr << "Problem with state switch test (WifiPhy idle)." << std::endl;
96  }
97  if (StateSwitchTest(WifiPhyState::CCA_BUSY))
98  {
99  return true;
100  std::cerr << "Problem with state switch test (WifiPhy cca busy)." << std::endl;
101  }
102  if (StateSwitchTest(WifiPhyState::TX))
103  {
104  return true;
105  std::cerr << "Problem with state switch test (WifiPhy tx)." << std::endl;
106  }
107  if (StateSwitchTest(WifiPhyState::RX))
108  {
109  return true;
110  std::cerr << "Problem with state switch test (WifiPhy rx)." << std::endl;
111  }
112  if (StateSwitchTest(WifiPhyState::SWITCHING))
113  {
114  return true;
115  std::cerr << "Problem with state switch test (WifiPhy switching)." << std::endl;
116  }
117  if (StateSwitchTest(WifiPhyState::SLEEP))
118  {
119  return true;
120  std::cerr << "Problem with state switch test (WifiPhy sleep)." << std::endl;
121  }
122  return false;
123 }
124 
125 bool
127 {
128  // create node
129  Ptr<Node> node = CreateObject<Node>();
130 
131  // create energy source
132  Ptr<BasicEnergySource> source = m_energySource.Create<BasicEnergySource>();
133  source->SetInitialEnergy(50);
134  // aggregate energy source to node
135  node->AggregateObject(source);
136  source->SetNode(node);
137 
138  // create device energy model
139  Ptr<WifiRadioEnergyModel> model = m_deviceEnergyModel.Create<WifiRadioEnergyModel>();
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
169 
170  // Calculate remaining energy at simulation stop time
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  {
189  case WifiPhyState::IDLE:
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;
204  case WifiPhyState::SLEEP:
205  current = devModel->GetSleepCurrentA();
206  break;
207  case WifiPhyState::OFF:
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  }
241 
242  return false; // no error
243 }
244 
245 // -------------------------------------------------------------------------- //
246 
252 {
253  public:
255  virtual ~BasicEnergyDepletionTest();
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 
299 bool
301 {
302  /*
303  * Run simulation with different simulation time and update interval.
304  */
305  bool ret = false;
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 = true;
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 
324 void
326 {
327  m_callbackCount++;
328 }
329 
330 bool
331 BasicEnergyDepletionTest::DepletionTestCase(double simTimeS, double updateIntervalS)
332 {
333  // create node
334  NodeContainer c;
335  c.Create(m_numOfNodes);
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
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();
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
408  if (m_numOfNodes != m_callbackCount)
409  {
410  std::cerr << "Not all callbacks are invoked!" << std::endl;
411  return true;
412  }
413 
414  return false;
415 }
416 
417 // -------------------------------------------------------------------------- //
418 
419 int
420 main(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:42
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 UpdateEnergySource() override
Implements UpdateEnergySource.
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.
void AggregateObject(Ptr< Object > other)
Aggregate two Objects together.
Definition: object.cc:259
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
Hold variables of type string.
Definition: string.h:56
helps to create WifiNetDevice objects
Definition: wifi-helper.h:324
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
@ DLT_IEEE802_11_RADIO
Include Radiotap link layer information.
Definition: wifi-helper.h:178
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)
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#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:1326
@ WIFI_STANDARD_80211b
devices
Definition: first.py:42
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:704
wifi
Definition: third.py:95
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.