View | Details | Raw Unified | Return to bug 1941
Collapse All | Expand All

(-)a/src/energy/examples/basic-energy-model-test.cc (+449 lines)
Line 0    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2010 Network Security Lab, University of Washington, Seattle.
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: He Wu <mdzz@u.washington.edu>
19
 */
20
21
#include "ns3/basic-energy-source.h"
22
#include "ns3/wifi-radio-energy-model.h"
23
#include "ns3/basic-energy-source-helper.h"
24
#include "ns3/wifi-radio-energy-model-helper.h"
25
#include "ns3/energy-source-container.h"
26
#include "ns3/device-energy-model-container.h"
27
#include "ns3/log.h"
28
#include "ns3/node.h"
29
#include "ns3/simulator.h"
30
#include "ns3/double.h"
31
#include "ns3/config.h"
32
#include "ns3/string.h"
33
#include "ns3/yans-wifi-helper.h"
34
#include "ns3/nqos-wifi-mac-helper.h"
35
#include <cmath>
36
37
using namespace ns3;
38
39
NS_LOG_COMPONENT_DEFINE ("BasicEnergyModelTestSuite");
40
41
/**
42
 * Test case of update remaining energy for BasicEnergySource and
43
 * WifiRadioEnergyModel.
44
 */
45
class BasicEnergyUpdateTest
46
{
47
public:
48
  BasicEnergyUpdateTest ();
49
  virtual ~BasicEnergyUpdateTest ();
50
51
  /**
52
   * Performs some tests involving state updates and the relative energy consumption
53
   * \return true is some error happened.
54
   */
55
  bool DoRun (void);
56
57
private:
58
  /**
59
   * \param state Radio state to switch to.
60
   * \return False if no error occurs.
61
   *
62
   * Runs simulation for a while, check if final state & remaining energy is
63
   * correctly updated.
64
   */
65
  bool StateSwitchTest (WifiPhy::State state);
66
67
private:
68
  double m_timeS;     // in seconds
69
  double m_tolerance; // tolerance for power estimation
70
71
  ObjectFactory m_energySource;
72
  ObjectFactory m_deviceEnergyModel;
73
};
74
75
BasicEnergyUpdateTest::BasicEnergyUpdateTest ()
76
{
77
  m_timeS = 15.5; // idle for 15 seconds before changing state
78
  m_tolerance = 1.0e-13;  //
79
}
80
81
BasicEnergyUpdateTest::~BasicEnergyUpdateTest ()
82
{
83
}
84
85
bool
86
BasicEnergyUpdateTest::DoRun (void)
87
{
88
  // set types
89
  m_energySource.SetTypeId ("ns3::BasicEnergySource");
90
  m_deviceEnergyModel.SetTypeId ("ns3::WifiRadioEnergyModel");
91
92
  uint8_t ret = 0;
93
94
  // run state switch tests
95
  if (StateSwitchTest (WifiPhy::IDLE))
96
    {
97
      ret = 1;
98
      std::cerr << "Problem with state switch test (WifiPhy idle)." << std::endl;
99
    }
100
  if (StateSwitchTest (WifiPhy::CCA_BUSY))
101
    {
102
      ret = 1;
103
      std::cerr << "Problem with state switch test (WifiPhy cca busy)." << std::endl;
104
    }
105
  if (StateSwitchTest (WifiPhy::TX))
106
    {
107
      ret = 1;
108
      std::cerr << "Problem with state switch test (WifiPhy tx)." << std::endl;
109
    }
110
  if (StateSwitchTest (WifiPhy::RX))
111
    {
112
      ret = 1;
113
      std::cerr << "Problem with state switch test (WifiPhy rx)." << std::endl;
114
    }
115
  if (StateSwitchTest (WifiPhy::SWITCHING))
116
    {
117
      ret = 1;
118
      std::cerr << "Problem with state switch test (WifiPhy switching)." << std::endl;
119
    }
120
  if (StateSwitchTest (WifiPhy::SLEEP))
121
    {
122
      ret = 1;
123
      std::cerr << "Problem with state switch test (WifiPhy sleep)." << std::endl;
124
    }
125
  return ret;
126
}
127
128
bool
129
BasicEnergyUpdateTest::StateSwitchTest (WifiPhy::State state)
130
{
131
  // create node
132
  Ptr<Node> node = CreateObject<Node> ();
133
134
  // create energy source
135
  Ptr<BasicEnergySource> source = m_energySource.Create<BasicEnergySource> ();
136
  // aggregate energy source to node
137
  node->AggregateObject (source);
138
139
  // create device energy model
140
  Ptr<WifiRadioEnergyModel> model =
141
    m_deviceEnergyModel.Create<WifiRadioEnergyModel> ();
142
  // set energy source pointer
143
  model->SetEnergySource (source);
144
  // add device energy model to model list in energy source
145
  source->AppendDeviceEnergyModel (model);
146
147
  // retrieve device energy model from energy source
148
  DeviceEnergyModelContainer models =
149
    source->FindDeviceEnergyModels ("ns3::WifiRadioEnergyModel");
150
  // check list
151
  if ((models.GetN () == 0))
152
    {
153
      std::cerr << "Model list is empty!." << std::endl;
154
      return true;
155
    }
156
  // get pointer
157
  Ptr<WifiRadioEnergyModel> devModel =
158
    DynamicCast<WifiRadioEnergyModel> (models.Get (0));
159
  // check pointer
160
  if ((devModel == 0))
161
    {
162
      std::cerr << "NULL pointer to device model!." << std::endl;
163
      return true;
164
    }
165
166
  /*
167
   * The radio will stay IDLE for m_timeS seconds. Then it will switch into a
168
   * different state.
169
   */
170
171
  // schedule change of state
172
  Simulator::Schedule (Seconds (m_timeS),
173
                       &WifiRadioEnergyModel::ChangeState, devModel, state);
174
175
  // Calculate remaining energy at simulation stop time
176
  Simulator::Schedule (Seconds (m_timeS * 2), 
177
                       &BasicEnergySource::UpdateEnergySource, source);
178
179
  double timeDelta = 0.000000001; // 1 nanosecond
180
  // run simulation; stop just after last scheduled event
181
  Simulator::Stop (Seconds (m_timeS * 2 + timeDelta));
182
  Simulator::Run ();
183
184
  // energy = current * voltage * time
185
186
  // calculate idle power consumption
187
  double estRemainingEnergy = source->GetInitialEnergy ();
188
  double voltage = source->GetSupplyVoltage ();
189
  estRemainingEnergy -= devModel->GetIdleCurrentA () * voltage * m_timeS;
190
191
  /*
192
   * Manually calculate the number of periodic updates performed by the source.
193
   * This is to check if the periodic updates are performed correctly.
194
   */
195
  double actualTime = m_timeS;
196
  actualTime /= source->GetEnergyUpdateInterval ().GetSeconds ();
197
  actualTime = floor (actualTime); // rounding for update interval
198
  actualTime *= source->GetEnergyUpdateInterval ().GetSeconds ();
199
200
  // calculate new state power consumption
201
  double current = 0.0;
202
  switch (state)
203
    {
204
    case WifiPhy::IDLE:
205
      current = devModel->GetIdleCurrentA ();
206
      break;
207
    case WifiPhy::CCA_BUSY:
208
      current = devModel->GetCcaBusyCurrentA ();
209
      break;
210
    case WifiPhy::TX:
211
      current = devModel->GetTxCurrentA ();
212
      break;
213
    case WifiPhy::RX:
214
      current = devModel->GetRxCurrentA ();
215
      break;
216
    case WifiPhy::SWITCHING:
217
      current = devModel->GetSwitchingCurrentA ();
218
      break;
219
    case WifiPhy::SLEEP:
220
      current = devModel->GetSleepCurrentA ();
221
      break;
222
    default:
223
      NS_FATAL_ERROR ("Undefined radio state: " << state);
224
      break;
225
    }
226
  estRemainingEnergy -= current * voltage * m_timeS;
227
228
  // obtain remaining energy from source
229
  double remainingEnergy = source->GetRemainingEnergy ();
230
  NS_LOG_DEBUG ("Remaining energy is " << remainingEnergy);
231
  NS_LOG_DEBUG ("Estimated remaining energy is " << estRemainingEnergy);
232
  NS_LOG_DEBUG ("Difference is " << estRemainingEnergy - remainingEnergy);
233
234
  // check remaining energy
235
  if ((remainingEnergy > (estRemainingEnergy + m_tolerance)) ||
236
      (remainingEnergy < (estRemainingEnergy - m_tolerance)))
237
    {
238
      std::cerr << "Incorrect remaining energy!" << std::endl;
239
      return true;
240
    }
241
242
  // obtain radio state
243
  WifiPhy::State endState = devModel->GetCurrentState ();
244
  NS_LOG_DEBUG ("Radio state is " << endState);
245
  // check end state
246
  if (endState != state)
247
    {
248
      std::cerr << "Incorrect end state!" << std::endl;
249
      return true;
250
    }
251
  Simulator::Destroy ();
252
253
  return false; // no error
254
}
255
256
// -------------------------------------------------------------------------- //
257
258
/**
259
 * Test case of energy depletion handling for BasicEnergySource and
260
 * WifiRadioEnergyModel.
261
 */
262
class BasicEnergyDepletionTest
263
{
264
public:
265
  BasicEnergyDepletionTest ();
266
  virtual ~BasicEnergyDepletionTest ();
267
268
  /**
269
   * Performs some tests involving energy depletion
270
   * \return true is some error happened.
271
   */
272
  bool DoRun (void);
273
274
private:
275
  /**
276
   * Callback invoked when energy is drained from source.
277
   */
278
  void DepletionHandler (void);
279
280
  /**
281
   * \param simTimeS Simulation time, in seconds.
282
   * \param updateIntervalS Device model update interval, in seconds.
283
   * \return False if all is good.
284
   *
285
   * Runs simulation with specified simulation time and update interval.
286
   */
287
  bool DepletionTestCase (double simTimeS, double updateIntervalS);
288
289
private:
290
  int m_numOfNodes;         // number of nodes in simulation
291
  int m_callbackCount;      // counter for # of callbacks invoked
292
  double m_simTimeS;        // maximum simulation time, in seconds
293
  double m_timeStepS;       // simulation time step size, in seconds
294
  double m_updateIntervalS; // update interval of each device model
295
296
};
297
298
BasicEnergyDepletionTest::BasicEnergyDepletionTest ()
299
{
300
  m_numOfNodes = 10;
301
  m_callbackCount = 0;
302
  m_simTimeS = 4.5;
303
  m_timeStepS = 0.5;
304
  m_updateIntervalS = 1.5;
305
}
306
307
BasicEnergyDepletionTest::~BasicEnergyDepletionTest ()
308
{
309
}
310
311
bool
312
BasicEnergyDepletionTest::DoRun (void)
313
{
314
  /*
315
   * Run simulation with different simulation time and update interval.
316
   */
317
  uint8_t ret = 0;
318
319
  for (double simTimeS = 0.0; simTimeS <= m_simTimeS; simTimeS += m_timeStepS)
320
    {
321
      for (double updateIntervalS = 0.5; updateIntervalS <= m_updateIntervalS;
322
           updateIntervalS += m_timeStepS)
323
        {
324
          if (DepletionTestCase (simTimeS, updateIntervalS))
325
            {
326
              ret = 1;
327
              std::cerr << "Depletion test case problem." << std::endl;
328
            }
329
          // reset callback count
330
          m_callbackCount = 0;
331
        }
332
    }
333
  return ret;
334
}
335
336
void
337
BasicEnergyDepletionTest::DepletionHandler (void)
338
{
339
  m_callbackCount++;
340
}
341
342
bool
343
BasicEnergyDepletionTest::DepletionTestCase (double simTimeS,
344
                                             double updateIntervalS)
345
{
346
  // create node
347
  NodeContainer c;
348
  c.Create (m_numOfNodes);
349
350
  std::string phyMode ("DsssRate1Mbps");
351
352
  // disable fragmentation for frames below 2200 bytes
353
  Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold",
354
                      StringValue ("2200"));
355
  // turn off RTS/CTS for frames below 2200 bytes
356
  Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold",
357
                      StringValue ("2200"));
358
  // Fix non-unicast data rate to be the same as that of unicast
359
  Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode",
360
                      StringValue (phyMode));
361
362
  // install YansWifiPhy
363
  WifiHelper wifi;
364
  wifi.SetStandard (WIFI_PHY_STANDARD_80211b);
365
366
  YansWifiPhyHelper wifiPhy =  YansWifiPhyHelper::Default ();
367
  /*
368
   * This is one parameter that matters when using FixedRssLossModel, set it to
369
   * zero; otherwise, gain will be added.
370
   */
371
  wifiPhy.Set ("RxGain", DoubleValue (0));
372
  // ns-3 supports RadioTap and Prism tracing extensions for 802.11b
373
  wifiPhy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO);
374
375
  YansWifiChannelHelper wifiChannel;
376
  wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
377
  wifiPhy.SetChannel (wifiChannel.Create ());
378
379
  // Add a non-QoS upper MAC, and disable rate control
380
  NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
381
  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
382
                                "DataMode", StringValue (phyMode),
383
                                "ControlMode", StringValue (phyMode));
384
  // Set it to ad-hoc mode
385
  wifiMac.SetType ("ns3::AdhocWifiMac");
386
  NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, c);
387
388
  /*
389
   * Create and install energy source and a single basic radio energy model on
390
   * the node using helpers.
391
   */
392
  // source helper
393
  BasicEnergySourceHelper basicSourceHelper;
394
  // set energy to 0 so that we deplete energy at the beginning of simulation
395
  basicSourceHelper.Set ("BasicEnergySourceInitialEnergyJ", DoubleValue (0.0));
396
  // set update interval
397
  basicSourceHelper.Set ("PeriodicEnergyUpdateInterval",
398
                         TimeValue (Seconds (updateIntervalS)));
399
  // install source
400
  EnergySourceContainer sources = basicSourceHelper.Install (c);
401
402
  // device energy model helper
403
  WifiRadioEnergyModelHelper radioEnergyHelper;
404
  // set energy depletion callback
405
  WifiRadioEnergyModel::WifiRadioEnergyDepletionCallback callback =
406
    MakeCallback (&BasicEnergyDepletionTest::DepletionHandler, this);
407
  radioEnergyHelper.SetDepletionCallback (callback);
408
  // install on node
409
  DeviceEnergyModelContainer deviceModels = radioEnergyHelper.Install (devices, sources);
410
411
  // run simulation
412
  Simulator::Stop (Seconds (simTimeS));
413
  Simulator::Run ();
414
  Simulator::Destroy ();
415
416
  NS_LOG_DEBUG ("Simulation time = " << simTimeS << "s");
417
  NS_LOG_DEBUG ("Update interval = " << updateIntervalS << "s");
418
  NS_LOG_DEBUG ("Expected callback count is " << m_numOfNodes);
419
  NS_LOG_DEBUG ("Actual callback count is " << m_callbackCount);
420
421
  // check result, call back should only be invoked once
422
  if (m_numOfNodes != m_callbackCount)
423
    {
424
      std::cerr << "Not all callbacks are invoked!" << std::endl;
425
      return true;
426
    }
427
428
  return false;
429
}
430
431
// -------------------------------------------------------------------------- //
432
433
int
434
main (int argc, char **argv)
435
{
436
  BasicEnergyUpdateTest testEnergyUpdate;
437
  if (testEnergyUpdate.DoRun ())
438
    {
439
      return 1;
440
    }
441
442
  BasicEnergyDepletionTest testEnergyDepletion;
443
  if (testEnergyDepletion.DoRun ())
444
    {
445
      return 1;
446
    }
447
448
  return 0;
449
}
(-)a/src/energy/test/rv-battery-model-test.cc (-77 / +77 lines)
 Lines 25-31    Link Here 
25
#include "ns3/energy-source-container.h"
25
#include "ns3/energy-source-container.h"
26
#include "ns3/device-energy-model-container.h"
26
#include "ns3/device-energy-model-container.h"
27
#include "ns3/log.h"
27
#include "ns3/log.h"
28
#include "ns3/test.h"
29
#include "ns3/node.h"
28
#include "ns3/node.h"
30
#include "ns3/simulator.h"
29
#include "ns3/simulator.h"
31
#include "ns3/double.h"
30
#include "ns3/double.h"
 Lines 40-69    Link Here 
40
NS_LOG_COMPONENT_DEFINE ("RvBatteryModelTestSuite");
39
NS_LOG_COMPONENT_DEFINE ("RvBatteryModelTestSuite");
41
40
42
/**
41
/**
43
 * Test case of update remaining energy for RvBatteryModel and
42
 * This example was originally devised as a test, then it was converted
44
 * WifiRadioEnergyModel.
43
 * to an example.
44
 *
45
 * The script tests the remaining energy for RvBatteryModel and
46
 * WifiRadioEnergyModel updates. It does so by
47
 * mimicking the procedure and results published in
48
 * D. Rakhmatov, S. Vrudhula, D.A. Wallach, "Battery lifetime prediction for energy-aware computing,"
49
 * Proceedings of the 2002 International Symposium on Low Power Electronics and Design, 2002. ISLPED '02.
50
 * doi: 10.1109/LPE.2002.146729
45
 */
51
 */
46
class BatteryLifetimeTest : public TestCase
52
class BatteryLifetimeTest
47
{
53
{
48
public:
54
public:
49
  BatteryLifetimeTest ();
55
  BatteryLifetimeTest ();
50
  virtual ~BatteryLifetimeTest ();
56
  virtual ~BatteryLifetimeTest ();
51
57
52
private:
53
  /**
58
  /**
54
   * Creates load profiles according to "Battery Lifetime Prediction for Energy-
59
   * Creates load profiles according to
55
   * Aware Computing" paper.
60
   * D. Rakhmatov, S. Vrudhula, D.A. Wallach, "Battery lifetime prediction for energy-aware computing,"
61
   * Proceedings of the 2002 International Symposium on Low Power Electronics and Design, 2002. ISLPED '02.
62
   * doi: 10.1109/LPE.2002.146729
56
   */
63
   */
57
  void CreateLoadProfiles (void);
64
  void CreateLoadProfiles (void);
58
65
59
  /**
66
  /**
60
   * \returns False if no error occurs.
61
   *
62
   * Runs test.
63
   */
64
  void DoRun (void);
65
66
  /**
67
   * \param load Load value, in Amperes (A).
67
   * \param load Load value, in Amperes (A).
68
   * \param expLifetime Expected lifetime.
68
   * \param expLifetime Expected lifetime.
69
   * \return False if no error occurs.
69
   * \return False if no error occurs.
 Lines 86-92    Link Here 
86
                         std::vector<Time> timeStamps,
86
                         std::vector<Time> timeStamps,
87
                         Time expLifetime);
87
                         Time expLifetime);
88
88
89
private:
90
  typedef struct LoadProfile
89
  typedef struct LoadProfile
91
  {
90
  {
92
    std::vector<double> loads;
91
    std::vector<double> loads;
 Lines 95-108    Link Here 
95
    Time dualFoilLifeTime;
94
    Time dualFoilLifeTime;
96
  } LoadProfile;
95
  } LoadProfile;
97
96
98
private:
99
  std::vector<LoadProfile> m_loadProfiles;
97
  std::vector<LoadProfile> m_loadProfiles;
100
  double m_alpha;
98
  double m_alpha;
101
  double m_beta;
99
  double m_beta;
102
};
100
};
103
101
104
BatteryLifetimeTest::BatteryLifetimeTest ()
102
BatteryLifetimeTest::BatteryLifetimeTest ()
105
  : TestCase ("RV battery model battery lifetime test case.")
106
{
103
{
107
  // Itsy battery
104
  // Itsy battery
108
  m_alpha = 35220;
105
  m_alpha = 35220;
 Lines 637-692    Link Here 
637
  timeStamps.clear ();
634
  timeStamps.clear ();
638
}
635
}
639
636
640
void
637
int
641
BatteryLifetimeTest::DoRun (void)
638
main (int argc, char **argv)
642
{
639
{
643
  NS_LOG_DEBUG ("Constant load run.");
640
  NS_LOG_DEBUG ("Constant load run.");
644
641
645
  // 640mA
642
  BatteryLifetimeTest test;
646
  NS_TEST_ASSERT_MSG_EQ (ConstantLoadTest (0.640, Seconds (2844.0)), false,  "Problems with constant load test (640mA).");
643
  int ret = 0;
647
  // 320mA
644
648
  NS_TEST_ASSERT_MSG_EQ (ConstantLoadTest (0.320, Seconds (6146.0)), false,  "Problems with constant load test (320mA).");
645
  if (test.ConstantLoadTest (0.640, Seconds (2844.0)))
649
  // 128mA
646
    {
650
  NS_TEST_ASSERT_MSG_EQ (ConstantLoadTest (0.128, Seconds (16052.0)), false,  "Problems with constant load test (128mA).");
647
      ret = 1;
651
  // 64mA
648
      std::cerr << "Problems with constant load test (640mA)." << std::endl;
652
  NS_TEST_ASSERT_MSG_EQ (ConstantLoadTest (0.064, Seconds (32561.0)), false,  "Problems with constant load test (64mA).");
649
    }
653
  // 32mA
650
  if (test.ConstantLoadTest (0.320, Seconds (6146.0)))
654
  NS_TEST_ASSERT_MSG_EQ (ConstantLoadTest (0.032, Seconds (65580.0)), false,  "Problems with constant load test (32).");
651
    {
652
      ret = 1;
653
      std::cerr << "Problems with constant load test (320mA)." << std::endl;
654
    }
655
  if (test.ConstantLoadTest (0.128, Seconds (16052.0)))
656
    {
657
      ret = 1;
658
      std::cerr << "Problems with constant load test (128mA)." << std::endl;
659
    }
660
  if (test.ConstantLoadTest (0.064, Seconds (32561.0)))
661
    {
662
      ret = 1;
663
      std::cerr << "Problems with constant load test (64mA)." << std::endl;
664
    }
665
  if (test.ConstantLoadTest (0.032, Seconds (65580.0)))
666
    {
667
      ret = 1;
668
      std::cerr << "Problems with constant load test (32mA)." << std::endl;
669
    }
655
670
656
  // create load profiles for variable load test
671
  // create load profiles for variable load test
657
  CreateLoadProfiles ();
672
  test.CreateLoadProfiles ();
658
673
659
  // variable load with Itsy battery
674
  // variable load with Itsy battery
660
  NS_LOG_DEBUG ("\n\nItsy");
675
  NS_LOG_DEBUG ("\n\nItsy");
661
  m_alpha = 35220;
676
  test.m_alpha = 35220;
662
  m_beta = 0.637;
677
  test.m_beta = 0.637;
663
  for (uint32_t i = 0; i < m_loadProfiles.size (); i++)
678
  for (uint32_t i = 0; i < test.m_loadProfiles.size (); i++)
664
    {
679
    {
665
      NS_LOG_DEBUG ("========");
680
      NS_LOG_DEBUG ("========");
666
      NS_LOG_DEBUG ("Variable load profile C" << i + 1);
681
      NS_LOG_DEBUG ("Variable load profile C" << i + 1);
667
      if (VariableLoadTest (m_loadProfiles[i].loads,
682
      if (test.VariableLoadTest (test.m_loadProfiles[i].loads,
668
                            m_loadProfiles[i].timeStamps,
683
                                 test.m_loadProfiles[i].timeStamps,
669
                            m_loadProfiles[i].itsyLifetime))
684
                                 test.m_loadProfiles[i].itsyLifetime))
670
        {
685
        {
671
          return;
686
          ret = 1;
687
          std::cerr << "Problems with variable load test (Itsy)." << std::endl;
672
        }
688
        }
673
    }
689
    }
674
690
675
  // variable load with DUALFOIL battery
691
  // variable load with DUALFOIL battery
676
  NS_LOG_DEBUG ("\n\nDUALFOIL");
692
  NS_LOG_DEBUG ("\n\nDUALFOIL");
677
  m_alpha = 40027;
693
  test.m_alpha = 40027;
678
  m_beta = 0.276;
694
  test.m_beta = 0.276;
679
  for (uint32_t i = 0; i < m_loadProfiles.size (); i++)
695
  for (uint32_t i = 0; i < test.m_loadProfiles.size (); i++)
680
    {
696
    {
681
      NS_LOG_DEBUG ("========");
697
      NS_LOG_DEBUG ("========");
682
      NS_LOG_DEBUG ("Variable load profile C" << i + 1);
698
      NS_LOG_DEBUG ("Variable load profile C" << i + 1);
683
      if (VariableLoadTest (m_loadProfiles[i].loads,
699
      if (test.VariableLoadTest (test.m_loadProfiles[i].loads,
684
                            m_loadProfiles[i].timeStamps,
700
                                 test.m_loadProfiles[i].timeStamps,
685
                            m_loadProfiles[i].dualFoilLifeTime))
701
                                 test.m_loadProfiles[i].dualFoilLifeTime))
686
        {
702
        {
687
          return;
703
          ret = 1;
704
          std::cerr << "Problems with variable load test (DUALFOIL)." << std::endl;
688
        }
705
        }
689
    }
706
    }
707
708
  return ret;
690
}
709
}
691
710
692
bool
711
bool
 Lines 761-774    Link Here 
761
  NS_LOG_DEBUG ("Expected lifetime = " << expLifetime.GetSeconds () << "s");
780
  NS_LOG_DEBUG ("Expected lifetime = " << expLifetime.GetSeconds () << "s");
762
  NS_LOG_DEBUG ("Actual lifetime = " << actualLifetime.GetSeconds () << "s");
781
  NS_LOG_DEBUG ("Actual lifetime = " << actualLifetime.GetSeconds () << "s");
763
782
764
  NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL (actualLifetime, expLifetime, "Incorrect lifetime!");
783
  Simulator::Destroy ();
765
  /*
766
  NS_TEST_ASSERT_MSG_EQ_TOL_RETURNS_BOOL (actualLifetime.GetSeconds () / 60,
767
                                         expLifetime.GetSeconds () / 60, 0.1,
768
                                         "Incorrect lifetime!");
769
   */
770
784
771
  Simulator::Destroy ();
785
  if (actualLifetime != expLifetime)
786
    {
787
      std::cerr << "ConstantLoadTest: Incorrect lifetime for load " << load << std::endl;
788
      return true;
789
    }
772
790
773
  return false; // error free
791
  return false; // error free
774
}
792
}
 Lines 859-892    Link Here 
859
  NS_LOG_DEBUG ("Actual lifetime = " << actualLifetime.GetSeconds () << "s");
877
  NS_LOG_DEBUG ("Actual lifetime = " << actualLifetime.GetSeconds () << "s");
860
  NS_LOG_DEBUG ("Difference = " << expLifetime.GetSeconds () - actualLifetime.GetSeconds () << "s");
878
  NS_LOG_DEBUG ("Difference = " << expLifetime.GetSeconds () - actualLifetime.GetSeconds () << "s");
861
879
862
  //NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL (actualLifetime, expLifetime, "Incorrect lifetime!");
880
  Simulator::Destroy ();
863
  NS_TEST_ASSERT_MSG_EQ_TOL_RETURNS_BOOL (actualLifetime.GetSeconds (), expLifetime.GetSeconds (),
864
                                          120, // error tolerance = 120s
865
                                          "Incorrect lifetime!");
866
881
867
  Simulator::Destroy ();
882
  // error tolerance = 120s
883
  if ((actualLifetime.GetSeconds ()) > (expLifetime.GetSeconds ()) + (120) ||
884
      (actualLifetime.GetSeconds ()) < (expLifetime.GetSeconds ()) - (120))
885
    {
886
      std::cerr << "VariableLoadTest: Incorrect lifetime." << std::endl;
887
      return true;
888
    }
868
889
869
  return false;   // error free
890
  return false;   // error free
870
}
891
}
871
892
872
// -------------------------------------------------------------------------- //
873
874
/**
875
 * Unit test suite for energy model. Although the test suite involves 2 modules
876
 * it is still considered a unit test. Because a DeviceEnergyModel cannot live
877
 * without an EnergySource.
878
 */
879
class RvBatteryModelTestSuite : public TestSuite
880
{
881
public:
882
  RvBatteryModelTestSuite ();
883
};
884
885
RvBatteryModelTestSuite::RvBatteryModelTestSuite ()
886
  : TestSuite ("rv-battery-model", SYSTEM)
887
{
888
  AddTestCase (new BatteryLifetimeTest, TestCase::QUICK);
889
}
890
891
// create an instance of the test suite
892
static RvBatteryModelTestSuite g_rvBatteryModelTestSuite;
(-)a/src/energy/examples/wscript (+7 lines)
 Lines 6-8    Link Here 
6
6
7
    obj = bld.create_ns3_program('li-ion-energy-source', ['core', 'energy'])
7
    obj = bld.create_ns3_program('li-ion-energy-source', ['core', 'energy'])
8
    obj.source = 'li-ion-energy-source.cc'
8
    obj.source = 'li-ion-energy-source.cc'
9
10
    obj = bld.create_ns3_program('rv-battery-model-test', ['core', 'energy', 'wifi'])
11
    obj.source = 'rv-battery-model-test.cc'
12
    
13
    obj = bld.create_ns3_program('basic-energy-model-test', ['core', 'energy', 'wifi'])
14
    obj.source = 'basic-energy-model-test.cc'
15
    
(-)a/src/energy/helper/wifi-radio-energy-model-helper.cc (-143 lines)
 Lines 1-143    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2010 Network Security Lab, University of Washington, Seattle.
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
 * Authors: Sidharth Nabar <snabar@uw.edu>, He Wu <mdzz@u.washington.edu>
19
 */
20
21
#include "wifi-radio-energy-model-helper.h"
22
#include "basic-energy-source-helper.h"
23
#include "ns3/wifi-phy.h"
24
#include "ns3/wifi-net-device.h"
25
#include "ns3/config.h"
26
#include "ns3/names.h"
27
#include "ns3/wifi-tx-current-model.h"
28
29
namespace ns3 {
30
31
WifiRadioEnergyModelHelper::WifiRadioEnergyModelHelper ()
32
{
33
  m_radioEnergy.SetTypeId ("ns3::WifiRadioEnergyModel");
34
  m_depletionCallback.Nullify ();
35
  m_rechargedCallback.Nullify ();
36
}
37
38
WifiRadioEnergyModelHelper::~WifiRadioEnergyModelHelper ()
39
{
40
}
41
42
void
43
WifiRadioEnergyModelHelper::Set (std::string name, const AttributeValue &v)
44
{
45
  m_radioEnergy.Set (name, v);
46
}
47
48
void
49
WifiRadioEnergyModelHelper::SetDepletionCallback (
50
  WifiRadioEnergyModel::WifiRadioEnergyDepletionCallback callback)
51
{
52
  m_depletionCallback = callback;
53
}
54
55
void
56
WifiRadioEnergyModelHelper::SetRechargedCallback (
57
  WifiRadioEnergyModel::WifiRadioEnergyRechargedCallback callback)
58
{
59
  m_rechargedCallback = callback;
60
}
61
62
void
63
WifiRadioEnergyModelHelper::SetTxCurrentModel (std::string name,
64
                                               std::string n0, const AttributeValue& v0,
65
                                               std::string n1, const AttributeValue& v1,
66
                                               std::string n2, const AttributeValue& v2,
67
                                               std::string n3, const AttributeValue& v3,
68
                                               std::string n4, const AttributeValue& v4,
69
                                               std::string n5, const AttributeValue& v5,
70
                                               std::string n6, const AttributeValue& v6,
71
                                               std::string n7, const AttributeValue& v7)
72
{
73
  ObjectFactory factory;
74
  factory.SetTypeId (name);
75
  factory.Set (n0, v0);
76
  factory.Set (n1, v1);
77
  factory.Set (n2, v2);
78
  factory.Set (n3, v3);
79
  factory.Set (n4, v4);
80
  factory.Set (n5, v5);
81
  factory.Set (n6, v6);
82
  factory.Set (n7, v7);
83
  m_txCurrentModel = factory;
84
}
85
86
87
/*
88
 * Private function starts here.
89
 */
90
91
Ptr<DeviceEnergyModel>
92
WifiRadioEnergyModelHelper::DoInstall (Ptr<NetDevice> device,
93
                                       Ptr<EnergySource> source) const
94
{
95
  NS_ASSERT (device != NULL);
96
  NS_ASSERT (source != NULL);
97
  // check if device is WifiNetDevice
98
  std::string deviceName = device->GetInstanceTypeId ().GetName ();
99
  if (deviceName.compare ("ns3::WifiNetDevice") != 0)
100
    {
101
      NS_FATAL_ERROR ("NetDevice type is not WifiNetDevice!");
102
    }
103
  Ptr<Node> node = device->GetNode ();
104
  Ptr<WifiRadioEnergyModel> model = m_radioEnergy.Create ()->GetObject<WifiRadioEnergyModel> ();
105
  NS_ASSERT (model != NULL);
106
  // set energy source pointer
107
  model->SetEnergySource (source);
108
  // set energy depletion callback
109
  // if none is specified, make a callback to WifiPhy::SetSleepMode
110
  Ptr<WifiNetDevice> wifiDevice = DynamicCast<WifiNetDevice> (device);
111
  Ptr<WifiPhy> wifiPhy = wifiDevice->GetPhy ();
112
  if (m_depletionCallback.IsNull ())
113
    {
114
      model->SetEnergyDepletionCallback (MakeCallback (&WifiPhy::SetSleepMode, wifiPhy));
115
    }
116
  else
117
    {
118
      model->SetEnergyDepletionCallback (m_depletionCallback);
119
    }
120
  // set energy recharged callback
121
  // if none is specified, make a callback to WifiPhy::ResumeFromSleep
122
  if (m_rechargedCallback.IsNull ())
123
    {
124
      model->SetEnergyRechargedCallback (MakeCallback (&WifiPhy::ResumeFromSleep, wifiPhy));
125
    }
126
  else
127
    {
128
      model->SetEnergyRechargedCallback (m_rechargedCallback);
129
    }
130
  // add model to device model list in energy source
131
  source->AppendDeviceEnergyModel (model);
132
  // create and register energy model phy listener
133
  wifiPhy->RegisterListener (model->GetPhyListener ());
134
  //
135
  if (m_txCurrentModel.GetTypeId ().GetUid ())
136
    {
137
      Ptr<WifiTxCurrentModel> txcurrent = m_txCurrentModel.Create<WifiTxCurrentModel> ();
138
      model->SetTxCurrentModel (txcurrent);
139
    }
140
  return model;
141
}
142
143
} // namespace ns3
(-)a/src/energy/helper/wifi-radio-energy-model-helper.h (-124 lines)
 Lines 1-124    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright (c) 2010 Network Security Lab, University of Washington, Seattle.
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: Sidharth Nabar <snabar@uw.edu>, He Wu <mdzz@u.washington.edu>
19
*/
20
21
#ifndef WIFI_RADIO_ENERGY_MODEL_HELPER_H
22
#define WIFI_RADIO_ENERGY_MODEL_HELPER_H
23
24
#include "energy-model-helper.h"
25
#include "ns3/wifi-radio-energy-model.h"
26
27
namespace ns3 {
28
29
/**
30
 * \ingroup energy
31
 * \brief Assign WifiRadioEnergyModel to wifi devices.
32
 *
33
 * This installer installs WifiRadioEnergyModel for only WifiNetDevice objects.
34
 *
35
 */
36
class WifiRadioEnergyModelHelper : public DeviceEnergyModelHelper
37
{
38
public:
39
  /**
40
   * Construct a helper which is used to add a radio energy model to a node
41
   */
42
  WifiRadioEnergyModelHelper ();
43
44
  /**
45
   * Destroy a RadioEnergy Helper
46
   */
47
  ~WifiRadioEnergyModelHelper ();
48
49
  /**
50
   * \param name the name of the attribute to set
51
   * \param v the value of the attribute
52
   *
53
   * Sets an attribute of the underlying PHY object.
54
   */
55
  void Set (std::string name, const AttributeValue &v);
56
57
  /**
58
   * \param callback Callback function for energy depletion handling.
59
   *
60
   * Sets the callback to be invoked when energy is depleted.
61
   */
62
  void SetDepletionCallback (
63
    WifiRadioEnergyModel::WifiRadioEnergyDepletionCallback callback);
64
65
  /**
66
   * \param callback Callback function for energy recharged handling.
67
   *
68
   * Sets the callback to be invoked when energy is recharged.
69
   */
70
  void SetRechargedCallback (
71
    WifiRadioEnergyModel::WifiRadioEnergyRechargedCallback callback);
72
73
  /**
74
   * \param name the name of the model to set
75
   * \param n0 the name of the attribute to set
76
   * \param v0 the value of the attribute to set
77
   * \param n1 the name of the attribute to set
78
   * \param v1 the value of the attribute to set
79
   * \param n2 the name of the attribute to set
80
   * \param v2 the value of the attribute to set
81
   * \param n3 the name of the attribute to set
82
   * \param v3 the value of the attribute to set
83
   * \param n4 the name of the attribute to set
84
   * \param v4 the value of the attribute to set
85
   * \param n5 the name of the attribute to set
86
   * \param v5 the value of the attribute to set
87
   * \param n6 the name of the attribute to set
88
   * \param v6 the value of the attribute to set
89
   * \param n7 the name of the attribute to set
90
   * \param v7 the value of the attribute to set
91
   *
92
   * Configure a propagation delay for this channel.
93
   */
94
  void SetTxCurrentModel (std::string name,
95
                          std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
96
                          std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
97
                          std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
98
                          std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
99
                          std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
100
                          std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
101
                          std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
102
                          std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
103
104
private:
105
  /**
106
   * \param device Pointer to the NetDevice to install DeviceEnergyModel.
107
   * \param source Pointer to EnergySource to install.
108
   *
109
   * Implements DeviceEnergyModel::Install.
110
   */
111
  virtual Ptr<DeviceEnergyModel> DoInstall (Ptr<NetDevice> device,
112
                                            Ptr<EnergySource> source) const;
113
114
private:
115
  ObjectFactory m_radioEnergy;
116
  WifiRadioEnergyModel::WifiRadioEnergyDepletionCallback m_depletionCallback;
117
  WifiRadioEnergyModel::WifiRadioEnergyRechargedCallback m_rechargedCallback;
118
  ObjectFactory m_txCurrentModel;
119
120
};
121
122
} // namespace ns3
123
124
#endif /* WIFI_RADIO_ENERGY_MODEL_HELPER_H */
(-)a/src/energy/model/wifi-radio-energy-model.cc (-572 lines)
 Lines 1-572    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2010 Network Security Lab, University of Washington, Seattle.
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: Sidharth Nabar <snabar@uw.edu>, He Wu <mdzz@u.washington.edu>
19
 */
20
21
#include "ns3/log.h"
22
#include "ns3/double.h"
23
#include "ns3/simulator.h"
24
#include "ns3/trace-source-accessor.h"
25
#include "ns3/pointer.h"
26
#include "energy-source.h"
27
#include "wifi-radio-energy-model.h"
28
#include "wifi-tx-current-model.h"
29
30
namespace ns3 {
31
32
NS_LOG_COMPONENT_DEFINE ("WifiRadioEnergyModel");
33
34
NS_OBJECT_ENSURE_REGISTERED (WifiRadioEnergyModel);
35
36
TypeId
37
WifiRadioEnergyModel::GetTypeId (void)
38
{
39
  static TypeId tid = TypeId ("ns3::WifiRadioEnergyModel")
40
    .SetParent<DeviceEnergyModel> ()
41
    .SetGroupName ("Energy")
42
    .AddConstructor<WifiRadioEnergyModel> ()
43
    .AddAttribute ("IdleCurrentA",
44
                   "The default radio Idle current in Ampere.",
45
                   DoubleValue (0.273),  // idle mode = 273mA
46
                   MakeDoubleAccessor (&WifiRadioEnergyModel::SetIdleCurrentA,
47
                                       &WifiRadioEnergyModel::GetIdleCurrentA),
48
                   MakeDoubleChecker<double> ())
49
    .AddAttribute ("CcaBusyCurrentA",
50
                   "The default radio CCA Busy State current in Ampere.",
51
                   DoubleValue (0.273),  // default to be the same as idle mode
52
                   MakeDoubleAccessor (&WifiRadioEnergyModel::SetCcaBusyCurrentA,
53
                                       &WifiRadioEnergyModel::GetCcaBusyCurrentA),
54
                   MakeDoubleChecker<double> ())
55
    .AddAttribute ("TxCurrentA",
56
                   "The radio Tx current in Ampere.",
57
                   DoubleValue (0.380),    // transmit at 0dBm = 380mA
58
                   MakeDoubleAccessor (&WifiRadioEnergyModel::SetTxCurrentA,
59
                                       &WifiRadioEnergyModel::GetTxCurrentA),
60
                   MakeDoubleChecker<double> ())
61
    .AddAttribute ("RxCurrentA",
62
                   "The radio Rx current in Ampere.",
63
                   DoubleValue (0.313),    // receive mode = 313mA
64
                   MakeDoubleAccessor (&WifiRadioEnergyModel::SetRxCurrentA,
65
                                       &WifiRadioEnergyModel::GetRxCurrentA),
66
                   MakeDoubleChecker<double> ())
67
    .AddAttribute ("SwitchingCurrentA",
68
                   "The default radio Channel Switch current in Ampere.",
69
                   DoubleValue (0.273),  // default to be the same as idle mode
70
                   MakeDoubleAccessor (&WifiRadioEnergyModel::SetSwitchingCurrentA,
71
                                       &WifiRadioEnergyModel::GetSwitchingCurrentA),
72
                   MakeDoubleChecker<double> ())
73
    .AddAttribute ("SleepCurrentA",
74
                   "The radio Sleep current in Ampere.",
75
                   DoubleValue (0.033),  // sleep mode = 33mA
76
                   MakeDoubleAccessor (&WifiRadioEnergyModel::SetSleepCurrentA,
77
                                       &WifiRadioEnergyModel::GetSleepCurrentA),
78
                   MakeDoubleChecker<double> ())
79
    .AddAttribute ("TxCurrentModel", "A pointer to the attached tx current model.",
80
                   PointerValue (),
81
                   MakePointerAccessor (&WifiRadioEnergyModel::m_txCurrentModel),
82
                   MakePointerChecker<WifiTxCurrentModel> ())
83
    .AddTraceSource ("TotalEnergyConsumption",
84
                     "Total energy consumption of the radio device.",
85
                     MakeTraceSourceAccessor (&WifiRadioEnergyModel::m_totalEnergyConsumption),
86
                     "ns3::TracedValue::DoubleCallback")
87
  ; 
88
  return tid;
89
}
90
91
WifiRadioEnergyModel::WifiRadioEnergyModel ()
92
{
93
  NS_LOG_FUNCTION (this);
94
  m_currentState = WifiPhy::IDLE;  // initially IDLE
95
  m_lastUpdateTime = Seconds (0.0);
96
  m_nPendingChangeState = 0;
97
  m_isSupersededChangeState = false;
98
  m_energyDepletionCallback.Nullify ();
99
  m_source = NULL;
100
  // set callback for WifiPhy listener
101
  m_listener = new WifiRadioEnergyModelPhyListener;
102
  m_listener->SetChangeStateCallback (MakeCallback (&DeviceEnergyModel::ChangeState, this));
103
  // set callback for updating the tx current
104
  m_listener->SetUpdateTxCurrentCallback (MakeCallback (&WifiRadioEnergyModel::SetTxCurrentFromModel, this));
105
}
106
107
WifiRadioEnergyModel::~WifiRadioEnergyModel ()
108
{
109
  NS_LOG_FUNCTION (this);
110
  delete m_listener;
111
}
112
113
void
114
WifiRadioEnergyModel::SetEnergySource (Ptr<EnergySource> source)
115
{
116
  NS_LOG_FUNCTION (this << source);
117
  NS_ASSERT (source != NULL);
118
  m_source = source;
119
}
120
121
double
122
WifiRadioEnergyModel::GetTotalEnergyConsumption (void) const
123
{
124
  NS_LOG_FUNCTION (this);
125
  return m_totalEnergyConsumption;
126
}
127
128
double
129
WifiRadioEnergyModel::GetIdleCurrentA (void) const
130
{
131
  NS_LOG_FUNCTION (this);
132
  return m_idleCurrentA;
133
}
134
135
void
136
WifiRadioEnergyModel::SetIdleCurrentA (double idleCurrentA)
137
{
138
  NS_LOG_FUNCTION (this << idleCurrentA);
139
  m_idleCurrentA = idleCurrentA;
140
}
141
142
double
143
WifiRadioEnergyModel::GetCcaBusyCurrentA (void) const
144
{
145
  NS_LOG_FUNCTION (this);
146
  return m_ccaBusyCurrentA;
147
}
148
149
void
150
WifiRadioEnergyModel::SetCcaBusyCurrentA (double CcaBusyCurrentA)
151
{
152
  NS_LOG_FUNCTION (this << CcaBusyCurrentA);
153
  m_ccaBusyCurrentA = CcaBusyCurrentA;
154
}
155
156
double
157
WifiRadioEnergyModel::GetTxCurrentA (void) const
158
{
159
  NS_LOG_FUNCTION (this);
160
  return m_txCurrentA;
161
}
162
163
void
164
WifiRadioEnergyModel::SetTxCurrentA (double txCurrentA)
165
{
166
  NS_LOG_FUNCTION (this << txCurrentA);
167
  m_txCurrentA = txCurrentA;
168
}
169
170
double
171
WifiRadioEnergyModel::GetRxCurrentA (void) const
172
{
173
  NS_LOG_FUNCTION (this);
174
  return m_rxCurrentA;
175
}
176
177
void
178
WifiRadioEnergyModel::SetRxCurrentA (double rxCurrentA)
179
{
180
  NS_LOG_FUNCTION (this << rxCurrentA);
181
  m_rxCurrentA = rxCurrentA;
182
}
183
184
double
185
WifiRadioEnergyModel::GetSwitchingCurrentA (void) const
186
{
187
  NS_LOG_FUNCTION (this);
188
  return m_switchingCurrentA;
189
}
190
191
void
192
WifiRadioEnergyModel::SetSwitchingCurrentA (double switchingCurrentA)
193
{
194
  NS_LOG_FUNCTION (this << switchingCurrentA);
195
  m_switchingCurrentA = switchingCurrentA;
196
}
197
198
double
199
WifiRadioEnergyModel::GetSleepCurrentA (void) const
200
{
201
  NS_LOG_FUNCTION (this);
202
  return m_sleepCurrentA;
203
}
204
205
void
206
WifiRadioEnergyModel::SetSleepCurrentA (double sleepCurrentA)
207
{
208
  NS_LOG_FUNCTION (this << sleepCurrentA);
209
  m_sleepCurrentA = sleepCurrentA;
210
}
211
212
WifiPhy::State
213
WifiRadioEnergyModel::GetCurrentState (void) const
214
{
215
  NS_LOG_FUNCTION (this);
216
  return m_currentState;
217
}
218
219
void
220
WifiRadioEnergyModel::SetEnergyDepletionCallback (
221
  WifiRadioEnergyDepletionCallback callback)
222
{
223
  NS_LOG_FUNCTION (this);
224
  if (callback.IsNull ())
225
    {
226
      NS_LOG_DEBUG ("WifiRadioEnergyModel:Setting NULL energy depletion callback!");
227
    }
228
  m_energyDepletionCallback = callback;
229
}
230
231
void
232
WifiRadioEnergyModel::SetEnergyRechargedCallback (
233
  WifiRadioEnergyRechargedCallback callback)
234
{
235
  NS_LOG_FUNCTION (this);
236
  if (callback.IsNull ())
237
    {
238
      NS_LOG_DEBUG ("WifiRadioEnergyModel:Setting NULL energy recharged callback!");
239
    }
240
  m_energyRechargedCallback = callback;
241
}
242
243
void
244
WifiRadioEnergyModel::SetTxCurrentModel (Ptr<WifiTxCurrentModel> model)
245
{
246
  m_txCurrentModel = model;
247
}
248
249
void
250
WifiRadioEnergyModel::SetTxCurrentFromModel (double txPowerDbm)
251
{
252
  if (m_txCurrentModel)
253
    {
254
      m_txCurrentA = m_txCurrentModel->CalcTxCurrent (txPowerDbm);
255
    }
256
}
257
258
void
259
WifiRadioEnergyModel::ChangeState (int newState)
260
{
261
  NS_LOG_FUNCTION (this << newState);
262
263
  Time duration = Simulator::Now () - m_lastUpdateTime;
264
  NS_ASSERT (duration.GetNanoSeconds () >= 0); // check if duration is valid
265
266
  // energy to decrease = current * voltage * time
267
  double energyToDecrease = 0.0;
268
  double supplyVoltage = m_source->GetSupplyVoltage ();
269
  switch (m_currentState)
270
    {
271
    case WifiPhy::IDLE:
272
      energyToDecrease = duration.GetSeconds () * m_idleCurrentA * supplyVoltage;
273
      break;
274
    case WifiPhy::CCA_BUSY:
275
      energyToDecrease = duration.GetSeconds () * m_ccaBusyCurrentA * supplyVoltage;
276
      break;
277
    case WifiPhy::TX:
278
      energyToDecrease = duration.GetSeconds () * m_txCurrentA * supplyVoltage;
279
      break;
280
    case WifiPhy::RX:
281
      energyToDecrease = duration.GetSeconds () * m_rxCurrentA * supplyVoltage;
282
      break;
283
    case WifiPhy::SWITCHING:
284
      energyToDecrease = duration.GetSeconds () * m_switchingCurrentA * supplyVoltage;
285
      break;
286
    case WifiPhy::SLEEP:
287
      energyToDecrease = duration.GetSeconds () * m_sleepCurrentA * supplyVoltage;
288
      break;
289
    default:
290
      NS_FATAL_ERROR ("WifiRadioEnergyModel:Undefined radio state: " << m_currentState);
291
    }
292
293
  // update total energy consumption
294
  m_totalEnergyConsumption += energyToDecrease;
295
296
  // update last update time stamp
297
  m_lastUpdateTime = Simulator::Now ();
298
299
  m_nPendingChangeState++;
300
301
  // notify energy source
302
  m_source->UpdateEnergySource ();
303
304
  // in case the energy source is found to be depleted during the last update, a callback might be
305
  // invoked that might cause a change in the Wifi PHY state (e.g., the PHY is put into SLEEP mode).
306
  // This in turn causes a new call to this member function, with the consequence that the previous
307
  // instance is resumed after the termination of the new instance. In particular, the state set
308
  // by the previous instance is erroneously the final state stored in m_currentState. The check below
309
  // ensures that previous instances do not change m_currentState.
310
311
  if (!m_isSupersededChangeState)
312
    {
313
      // update current state & last update time stamp
314
      SetWifiRadioState ((WifiPhy::State) newState);
315
316
      // some debug message
317
      NS_LOG_DEBUG ("WifiRadioEnergyModel:Total energy consumption is " <<
318
                    m_totalEnergyConsumption << "J");
319
    }
320
321
  m_isSupersededChangeState = (m_nPendingChangeState > 1);
322
323
  m_nPendingChangeState--;
324
}
325
326
void
327
WifiRadioEnergyModel::HandleEnergyDepletion (void)
328
{
329
  NS_LOG_FUNCTION (this);
330
  NS_LOG_DEBUG ("WifiRadioEnergyModel:Energy is depleted!");
331
  // invoke energy depletion callback, if set.
332
  if (!m_energyDepletionCallback.IsNull ())
333
    {
334
      m_energyDepletionCallback ();
335
    }
336
}
337
338
void
339
WifiRadioEnergyModel::HandleEnergyRecharged (void)
340
{
341
  NS_LOG_FUNCTION (this);
342
  NS_LOG_DEBUG ("WifiRadioEnergyModel:Energy is recharged!");
343
  // invoke energy recharged callback, if set.
344
  if (!m_energyRechargedCallback.IsNull ())
345
    {
346
      m_energyRechargedCallback ();
347
    }
348
}
349
350
WifiRadioEnergyModelPhyListener *
351
WifiRadioEnergyModel::GetPhyListener (void)
352
{
353
  NS_LOG_FUNCTION (this);
354
  return m_listener;
355
}
356
357
/*
358
 * Private functions start here.
359
 */
360
361
void
362
WifiRadioEnergyModel::DoDispose (void)
363
{
364
  NS_LOG_FUNCTION (this);
365
  m_source = NULL;
366
  m_energyDepletionCallback.Nullify ();
367
}
368
369
double
370
WifiRadioEnergyModel::DoGetCurrentA (void) const
371
{
372
  NS_LOG_FUNCTION (this);
373
  switch (m_currentState)
374
    {
375
    case WifiPhy::IDLE:
376
      return m_idleCurrentA;
377
    case WifiPhy::CCA_BUSY:
378
      return m_ccaBusyCurrentA;
379
    case WifiPhy::TX:
380
      return m_txCurrentA;
381
    case WifiPhy::RX:
382
      return m_rxCurrentA;
383
    case WifiPhy::SWITCHING:
384
      return m_switchingCurrentA;
385
    case WifiPhy::SLEEP:
386
      return m_sleepCurrentA;
387
    default:
388
      NS_FATAL_ERROR ("WifiRadioEnergyModel:Undefined radio state:" << m_currentState);
389
    }
390
}
391
392
void
393
WifiRadioEnergyModel::SetWifiRadioState (const WifiPhy::State state)
394
{
395
  NS_LOG_FUNCTION (this << state);
396
  m_currentState = state;
397
  std::string stateName;
398
  switch (state)
399
    {
400
    case WifiPhy::IDLE:
401
      stateName = "IDLE";
402
      break;
403
    case WifiPhy::CCA_BUSY:
404
      stateName = "CCA_BUSY";
405
      break;
406
    case WifiPhy::TX:
407
      stateName = "TX";
408
      break;
409
    case WifiPhy::RX:
410
      stateName = "RX";
411
      break;
412
    case WifiPhy::SWITCHING:
413
      stateName = "SWITCHING";
414
      break;
415
    case WifiPhy::SLEEP:
416
      stateName = "SLEEP";
417
      break;
418
    }
419
  NS_LOG_DEBUG ("WifiRadioEnergyModel:Switching to state: " << stateName <<
420
                " at time = " << Simulator::Now ());
421
}
422
423
// -------------------------------------------------------------------------- //
424
425
WifiRadioEnergyModelPhyListener::WifiRadioEnergyModelPhyListener ()
426
{
427
  NS_LOG_FUNCTION (this);
428
  m_changeStateCallback.Nullify ();
429
  m_updateTxCurrentCallback.Nullify ();
430
}
431
432
WifiRadioEnergyModelPhyListener::~WifiRadioEnergyModelPhyListener ()
433
{
434
  NS_LOG_FUNCTION (this);
435
}
436
437
void
438
WifiRadioEnergyModelPhyListener::SetChangeStateCallback (DeviceEnergyModel::ChangeStateCallback callback)
439
{
440
  NS_LOG_FUNCTION (this << &callback);
441
  NS_ASSERT (!callback.IsNull ());
442
  m_changeStateCallback = callback;
443
}
444
445
void
446
WifiRadioEnergyModelPhyListener::SetUpdateTxCurrentCallback (UpdateTxCurrentCallback callback)
447
{
448
  NS_LOG_FUNCTION (this << &callback);
449
  NS_ASSERT (!callback.IsNull ());
450
  m_updateTxCurrentCallback = callback;
451
}
452
453
void
454
WifiRadioEnergyModelPhyListener::NotifyRxStart (Time duration)
455
{
456
  NS_LOG_FUNCTION (this << duration);
457
  if (m_changeStateCallback.IsNull ())
458
    {
459
      NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
460
    }
461
  m_changeStateCallback (WifiPhy::RX);
462
  m_switchToIdleEvent.Cancel ();
463
}
464
465
void
466
WifiRadioEnergyModelPhyListener::NotifyRxEndOk (void)
467
{
468
  NS_LOG_FUNCTION (this);
469
  if (m_changeStateCallback.IsNull ())
470
    {
471
      NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
472
    }
473
  m_changeStateCallback (WifiPhy::IDLE);
474
}
475
476
void
477
WifiRadioEnergyModelPhyListener::NotifyRxEndError (void)
478
{
479
  NS_LOG_FUNCTION (this);
480
  if (m_changeStateCallback.IsNull ())
481
    {
482
      NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
483
    }
484
  m_changeStateCallback (WifiPhy::IDLE);
485
}
486
487
void
488
WifiRadioEnergyModelPhyListener::NotifyTxStart (Time duration, double txPowerDbm)
489
{
490
  NS_LOG_FUNCTION (this << duration << txPowerDbm);
491
  if (m_updateTxCurrentCallback.IsNull ())
492
    {
493
      NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Update tx current callback not set!");
494
    }
495
  m_updateTxCurrentCallback (txPowerDbm);
496
  if (m_changeStateCallback.IsNull ())
497
    {
498
      NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
499
    }
500
  m_changeStateCallback (WifiPhy::TX);
501
  // schedule changing state back to IDLE after TX duration
502
  m_switchToIdleEvent.Cancel ();
503
  m_switchToIdleEvent = Simulator::Schedule (duration, &WifiRadioEnergyModelPhyListener::SwitchToIdle, this);
504
}
505
506
void
507
WifiRadioEnergyModelPhyListener::NotifyMaybeCcaBusyStart (Time duration)
508
{
509
  NS_LOG_FUNCTION (this << duration);
510
  if (m_changeStateCallback.IsNull ())
511
    {
512
      NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
513
    }
514
  m_changeStateCallback (WifiPhy::CCA_BUSY);
515
  // schedule changing state back to IDLE after CCA_BUSY duration
516
  m_switchToIdleEvent.Cancel ();
517
  m_switchToIdleEvent = Simulator::Schedule (duration, &WifiRadioEnergyModelPhyListener::SwitchToIdle, this);
518
}
519
520
void
521
WifiRadioEnergyModelPhyListener::NotifySwitchingStart (Time duration)
522
{
523
  NS_LOG_FUNCTION (this << duration);
524
  if (m_changeStateCallback.IsNull ())
525
    {
526
      NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
527
    }
528
  m_changeStateCallback (WifiPhy::SWITCHING);
529
  // schedule changing state back to IDLE after CCA_BUSY duration
530
  m_switchToIdleEvent.Cancel ();
531
  m_switchToIdleEvent = Simulator::Schedule (duration, &WifiRadioEnergyModelPhyListener::SwitchToIdle, this);
532
}
533
534
void
535
WifiRadioEnergyModelPhyListener::NotifySleep (void)
536
{
537
  NS_LOG_FUNCTION (this);
538
  if (m_changeStateCallback.IsNull ())
539
    {
540
      NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
541
    }
542
  m_changeStateCallback (WifiPhy::SLEEP);
543
  m_switchToIdleEvent.Cancel ();
544
}
545
546
void
547
WifiRadioEnergyModelPhyListener::NotifyWakeup(void)
548
{
549
  NS_LOG_FUNCTION (this);
550
  if (m_changeStateCallback.IsNull ())
551
    {
552
      NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
553
    }
554
  m_changeStateCallback (WifiPhy::IDLE);
555
}
556
557
/*
558
 * Private function state here.
559
 */
560
561
void
562
WifiRadioEnergyModelPhyListener::SwitchToIdle (void)
563
{
564
  NS_LOG_FUNCTION (this);
565
  if (m_changeStateCallback.IsNull ())
566
    {
567
      NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
568
    }
569
  m_changeStateCallback (WifiPhy::IDLE);
570
}
571
572
} // namespace ns3
(-)a/src/energy/model/wifi-radio-energy-model.h (-363 lines)
 Lines 1-363    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2010 Network Security Lab, University of Washington, Seattle.
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
 * Authors: Sidharth Nabar <snabar@uw.edu>, He Wu <mdzz@u.washington.edu>
19
 */
20
21
#ifndef WIFI_RADIO_ENERGY_MODEL_H
22
#define WIFI_RADIO_ENERGY_MODEL_H
23
24
#include "ns3/device-energy-model.h"
25
#include "ns3/nstime.h"
26
#include "ns3/event-id.h"
27
#include "ns3/traced-value.h"
28
#include "ns3/wifi-phy.h"
29
30
namespace ns3 {
31
32
class WifiTxCurrentModel;
33
34
/**
35
 * \ingroup energy
36
 * A WifiPhy listener class for notifying the WifiRadioEnergyModel of Wifi radio
37
 * state change.
38
 *
39
 */
40
class WifiRadioEnergyModelPhyListener : public WifiPhyListener
41
{
42
public:
43
  /**
44
   * Callback type for updating the transmit current based on the nominal tx power.
45
   */
46
  typedef Callback<void, double> UpdateTxCurrentCallback;
47
48
  WifiRadioEnergyModelPhyListener ();
49
  virtual ~WifiRadioEnergyModelPhyListener ();
50
51
  /**
52
   * \brief Sets the change state callback. Used by helper class.
53
   *
54
   * \param callback Change state callback.
55
   */
56
  void SetChangeStateCallback (DeviceEnergyModel::ChangeStateCallback callback);
57
58
  /**
59
   * \brief Sets the update tx current callback.
60
   *
61
   * \param callback Update tx current callback.
62
   */
63
  void SetUpdateTxCurrentCallback (UpdateTxCurrentCallback callback);
64
65
  /**
66
   * \brief Switches the WifiRadioEnergyModel to RX state.
67
   *
68
   * \param duration the expected duration of the packet reception.
69
   *
70
   * Defined in ns3::WifiPhyListener
71
   */
72
  virtual void NotifyRxStart (Time duration);
73
74
  /**
75
   * \brief Switches the WifiRadioEnergyModel back to IDLE state.
76
   *
77
   * Defined in ns3::WifiPhyListener
78
   *
79
   * Note that for the WifiRadioEnergyModel, the behavior of the function is the
80
   * same as NotifyRxEndError.
81
   */
82
  virtual void NotifyRxEndOk (void);
83
84
  /**
85
   * \brief Switches the WifiRadioEnergyModel back to IDLE state.
86
   *
87
   * Defined in ns3::WifiPhyListener
88
   *
89
   * Note that for the WifiRadioEnergyModel, the behavior of the function is the
90
   * same as NotifyRxEndOk.
91
   */
92
  virtual void NotifyRxEndError (void);
93
94
  /**
95
   * \brief Switches the WifiRadioEnergyModel to TX state and switches back to
96
   * IDLE after TX duration.
97
   *
98
   * \param duration the expected transmission duration.
99
   * \param txPowerDbm the nominal tx power in dBm
100
   *
101
   * Defined in ns3::WifiPhyListener
102
   */
103
  virtual void NotifyTxStart (Time duration, double txPowerDbm);
104
105
  /**
106
   * \param duration the expected busy duration.
107
   *
108
   * Defined in ns3::WifiPhyListener
109
   */
110
  virtual void NotifyMaybeCcaBusyStart (Time duration);
111
112
  /**
113
   * \param duration the expected channel switching duration.
114
   *
115
   * Defined in ns3::WifiPhyListener
116
   */
117
  virtual void NotifySwitchingStart (Time duration);
118
119
  /**
120
   * Defined in ns3::WifiPhyListener
121
   */
122
  virtual void NotifySleep (void);
123
124
  /**
125
   * Defined in ns3::WifiPhyListener
126
   */
127
  virtual void NotifyWakeup (void);
128
129
private:
130
  /**
131
   * A helper function that makes scheduling m_changeStateCallback possible.
132
   */
133
  void SwitchToIdle (void);
134
135
private:
136
  /**
137
   * Change state callback used to notify the WifiRadioEnergyModel of a state
138
   * change.
139
   */
140
  DeviceEnergyModel::ChangeStateCallback m_changeStateCallback;
141
142
  /**
143
   * Callback used to update the tx current stored in WifiRadioEnergyModel based on 
144
   * the nominal tx power used to transmit the current frame.
145
   */
146
  UpdateTxCurrentCallback m_updateTxCurrentCallback;
147
148
  EventId m_switchToIdleEvent;
149
};
150
151
// -------------------------------------------------------------------------- //
152
153
/**
154
 * \ingroup energy
155
 * \brief A WiFi radio energy model.
156
 * 
157
 * 4 states are defined for the radio: TX, RX, IDLE, SLEEP. Default state is
158
 * IDLE.
159
 * The different types of transactions that are defined are: 
160
 *  1. Tx: State goes from IDLE to TX, radio is in TX state for TX_duration,
161
 *     then state goes from TX to IDLE.
162
 *  2. Rx: State goes from IDLE to RX, radio is in RX state for RX_duration,
163
 *     then state goes from RX to IDLE.
164
 *  3. Go_to_Sleep: State goes from IDLE to SLEEP.
165
 *  4. End_of_Sleep: State goes from SLEEP to IDLE.
166
 * The class keeps track of what state the radio is currently in.
167
 *
168
 * Energy calculation: For each transaction, this model notifies EnergySource
169
 * object. The EnergySource object will query this model for the total current.
170
 * Then the EnergySource object uses the total current to calculate energy.
171
 *
172
 * Default values for power consumption are based on measurements reported in:
173
 * 
174
 * Daniel Halperin, Ben Greenstein, Anmol Sheth, David Wetherall,
175
 * "Demystifying 802.11n power consumption", Proceedings of HotPower'10 
176
 * 
177
 * Power consumption in Watts (single antenna):
178
 * 
179
 * \f$ P_{tx} = 1.14 \f$ (transmit at 0dBm)
180
 * 
181
 * \f$ P_{rx} = 0.94 \f$
182
 * 
183
 * \f$ P_{idle} = 0.82 \f$
184
 * 
185
 * \f$ P_{sleep} = 0.10 \f$
186
 * 
187
 * Hence, considering the default supply voltage of 3.0 V for the basic energy
188
 * source, the default current values in Ampere are:
189
 * 
190
 * \f$ I_{tx} = 0.380 \f$
191
 * 
192
 * \f$ I_{rx} = 0.313 \f$
193
 * 
194
 * \f$ I_{idle} = 0.273 \f$
195
 * 
196
 * \f$ I_{sleep} = 0.033 \f$
197
 * 
198
 * The dependence of the power consumption in transmission mode on the nominal
199
 * transmit power can also be achieved through a wifi tx current model.
200
 *
201
 */
202
class WifiRadioEnergyModel : public DeviceEnergyModel
203
{
204
public:
205
  /**
206
   * Callback type for energy depletion handling.
207
   */
208
  typedef Callback<void> WifiRadioEnergyDepletionCallback;
209
210
  /**
211
   * Callback type for energy recharged handling.
212
   */
213
  typedef Callback<void> WifiRadioEnergyRechargedCallback;
214
215
public:
216
  static TypeId GetTypeId (void);
217
  WifiRadioEnergyModel ();
218
  virtual ~WifiRadioEnergyModel ();
219
220
  /**
221
   * \brief Sets pointer to EnergySouce installed on node.
222
   *
223
   * \param source Pointer to EnergySource installed on node.
224
   *
225
   * Implements DeviceEnergyModel::SetEnergySource.
226
   */
227
  virtual void SetEnergySource (Ptr<EnergySource> source);
228
229
  /**
230
   * \returns Total energy consumption of the wifi device.
231
   *
232
   * Implements DeviceEnergyModel::GetTotalEnergyConsumption.
233
   */
234
  virtual double GetTotalEnergyConsumption (void) const;
235
236
  // Setter & getters for state power consumption.
237
  double GetIdleCurrentA (void) const;
238
  void SetIdleCurrentA (double idleCurrentA);
239
  double GetCcaBusyCurrentA (void) const;
240
  void SetCcaBusyCurrentA (double ccaBusyCurrentA);
241
  double GetTxCurrentA (void) const;
242
  void SetTxCurrentA (double txCurrentA);
243
  double GetRxCurrentA (void) const;
244
  void SetRxCurrentA (double rxCurrentA);
245
  double GetSwitchingCurrentA (void) const;
246
  void SetSwitchingCurrentA (double switchingCurrentA);
247
  double GetSleepCurrentA (void) const;
248
  void SetSleepCurrentA (double sleepCurrentA);
249
250
  /**
251
   * \returns Current state.
252
   */
253
  WifiPhy::State GetCurrentState (void) const;
254
255
  /**
256
   * \param callback Callback function.
257
   *
258
   * Sets callback for energy depletion handling.
259
   */
260
  void SetEnergyDepletionCallback (WifiRadioEnergyDepletionCallback callback);
261
262
  /**
263
   * \param callback Callback function.
264
   *
265
   * Sets callback for energy recharged handling.
266
   */
267
  void SetEnergyRechargedCallback (WifiRadioEnergyRechargedCallback callback);
268
269
  /**
270
   * \param model the model used to compute the wifi tx current.
271
   */
272
  void SetTxCurrentModel (Ptr<WifiTxCurrentModel> model);
273
274
  /**
275
   * \brief Calls the CalcTxCurrent method of the tx current model to
276
   *        compute the tx current based on such model
277
   * 
278
   * \param txPowerDbm the nominal tx power in dBm
279
   */
280
  void SetTxCurrentFromModel (double txPowerDbm);
281
282
  /**
283
   * \brief Changes state of the WifiRadioEnergyMode.
284
   *
285
   * \param newState New state the wifi radio is in.
286
   *
287
   * Implements DeviceEnergyModel::ChangeState.
288
   */
289
  virtual void ChangeState (int newState);
290
291
  /**
292
   * \brief Handles energy depletion.
293
   *
294
   * Implements DeviceEnergyModel::HandleEnergyDepletion
295
   */
296
  virtual void HandleEnergyDepletion (void);
297
298
  /**
299
   * \brief Handles energy recharged.
300
   *
301
   * Implements DeviceEnergyModel::HandleEnergyRecharged
302
   */
303
  virtual void HandleEnergyRecharged (void);
304
305
  /**
306
   * \returns Pointer to the PHY listener.
307
   */
308
  WifiRadioEnergyModelPhyListener * GetPhyListener (void);
309
310
311
private:
312
  void DoDispose (void);
313
314
  /**
315
   * \returns Current draw of device, at current state.
316
   *
317
   * Implements DeviceEnergyModel::GetCurrentA.
318
   */
319
  virtual double DoGetCurrentA (void) const;
320
321
  /**
322
   * \param state New state the radio device is currently in.
323
   *
324
   * Sets current state. This function is private so that only the energy model
325
   * can change its own state.
326
   */
327
  void SetWifiRadioState (const WifiPhy::State state);
328
329
private:
330
  Ptr<EnergySource> m_source;
331
332
  // Member variables for current draw in different radio modes.
333
  double m_txCurrentA;
334
  double m_rxCurrentA;
335
  double m_idleCurrentA;
336
  double m_ccaBusyCurrentA;
337
  double m_switchingCurrentA;
338
  double m_sleepCurrentA;
339
  Ptr<WifiTxCurrentModel> m_txCurrentModel;
340
341
  // This variable keeps track of the total energy consumed by this model.
342
  TracedValue<double> m_totalEnergyConsumption;
343
344
  // State variables.
345
  WifiPhy::State m_currentState;  // current state the radio is in
346
  Time m_lastUpdateTime;          // time stamp of previous energy update
347
348
  uint8_t m_nPendingChangeState;
349
  bool m_isSupersededChangeState;
350
351
  // Energy depletion callback
352
  WifiRadioEnergyDepletionCallback m_energyDepletionCallback;
353
354
  // Energy recharged callback
355
  WifiRadioEnergyRechargedCallback m_energyRechargedCallback;
356
357
  // WifiPhy listener
358
  WifiRadioEnergyModelPhyListener *m_listener;
359
};
360
361
} // namespace ns3
362
363
#endif /* WIFI_RADIO_ENERGY_MODEL_H */
(-)a/src/energy/model/wifi-tx-current-model.cc (-143 lines)
 Lines 1-143    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2014 Universita' degli Studi di Napoli "Federico II"
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: Stefano Avallone <stefano.avallone@unina.it>
19
 */
20
21
#include "wifi-tx-current-model.h"
22
#include "ns3/log.h"
23
#include "ns3/boolean.h"
24
#include "ns3/double.h"
25
#include "ns3/string.h"
26
#include "ns3/pointer.h"
27
#include <cmath>
28
29
namespace ns3 {
30
31
NS_LOG_COMPONENT_DEFINE ("WifiTxCurrentModel");
32
33
// ------------------------------------------------------------------------- //
34
35
NS_OBJECT_ENSURE_REGISTERED (WifiTxCurrentModel);
36
37
TypeId 
38
WifiTxCurrentModel::GetTypeId (void)
39
{
40
  static TypeId tid = TypeId ("ns3::WifiTxCurrentModel")
41
    .SetParent<Object> ()
42
    .SetGroupName ("Energy")
43
  ;
44
  return tid;
45
}
46
47
WifiTxCurrentModel::WifiTxCurrentModel()
48
{
49
}
50
51
WifiTxCurrentModel::~WifiTxCurrentModel()
52
{
53
}
54
55
double
56
WifiTxCurrentModel::DbmToW (double dbm)
57
{
58
  double mW = std::pow (10.0, dbm / 10.0);
59
  return mW / 1000.0;
60
}
61
62
// ------------------------------------------------------------------------- //
63
64
NS_OBJECT_ENSURE_REGISTERED (LinearWifiTxCurrentModel);
65
66
TypeId 
67
LinearWifiTxCurrentModel::GetTypeId (void)
68
{
69
  static TypeId tid = TypeId ("ns3::LinearWifiTxCurrentModel")
70
    .SetParent<WifiTxCurrentModel> ()
71
    .AddConstructor<LinearWifiTxCurrentModel> ()
72
    .AddAttribute ("Eta", "The efficiency of the power amplifier.",
73
                   DoubleValue (0.10),
74
                   MakeDoubleAccessor (&LinearWifiTxCurrentModel::SetEta,
75
                                       &LinearWifiTxCurrentModel::GetEta),
76
                   MakeDoubleChecker<double> ())
77
    .AddAttribute ("Voltage", "The supply voltage (in Volts).",
78
                   DoubleValue (3.0),
79
                   MakeDoubleAccessor (&LinearWifiTxCurrentModel::SetVoltage,
80
                                       &LinearWifiTxCurrentModel::GetVoltage),
81
                   MakeDoubleChecker<double> ())
82
    .AddAttribute ("IdleCurrent", "The current in the IDLE state (in Watts).",
83
                   DoubleValue (0.273333),
84
                   MakeDoubleAccessor (&LinearWifiTxCurrentModel::SetIdleCurrent,
85
                                       &LinearWifiTxCurrentModel::GetIdleCurrent),
86
                   MakeDoubleChecker<double> ())
87
  ;
88
  return tid;
89
}
90
91
LinearWifiTxCurrentModel::LinearWifiTxCurrentModel ()
92
{
93
}
94
95
LinearWifiTxCurrentModel::~LinearWifiTxCurrentModel()
96
{
97
}
98
99
void
100
LinearWifiTxCurrentModel::SetEta (double eta)
101
{
102
  m_eta = eta;
103
}
104
105
void
106
LinearWifiTxCurrentModel::SetVoltage (double voltage)
107
{
108
  m_voltage = voltage;
109
}
110
111
void
112
LinearWifiTxCurrentModel::SetIdleCurrent (double idleCurrent)
113
{
114
  m_idleCurrent = idleCurrent;
115
}
116
117
double
118
LinearWifiTxCurrentModel::GetEta (void) const
119
{
120
  return m_eta;
121
}
122
123
double
124
LinearWifiTxCurrentModel::GetVoltage (void) const
125
{
126
  return m_voltage;
127
}
128
129
double
130
LinearWifiTxCurrentModel::GetIdleCurrent (void) const
131
{
132
  return m_idleCurrent;
133
}
134
135
double
136
LinearWifiTxCurrentModel::CalcTxCurrent (double txPowerDbm) const
137
{
138
  return DbmToW (txPowerDbm) / (m_voltage * m_eta) + m_idleCurrent;
139
}
140
141
// ------------------------------------------------------------------------- //
142
143
} // namespace ns3
(-)a/src/energy/model/wifi-tx-current-model.h (-142 lines)
 Lines 1-142    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2014 Universita' degli Studi di Napoli "Federico II"
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: Stefano Avallone <stefano.avallone@unina.it>
19
 */
20
21
#ifndef WIFI_TX_CURRENT_MODEL_H
22
#define WIFI_TX_CURRENT_MODEL_H
23
24
#include "ns3/object.h"
25
26
namespace ns3 {
27
28
/**
29
 * \ingroup energy
30
 * 
31
 * \brief Modelize the transmit current as a function of the transmit power and mode
32
 *
33
 */
34
class WifiTxCurrentModel : public Object
35
{
36
public:
37
  static TypeId GetTypeId (void);
38
39
  WifiTxCurrentModel ();
40
  virtual ~WifiTxCurrentModel ();
41
42
  /**
43
   * \param txPowerDbm the nominal tx power in dBm
44
   * \returns the transmit current (in Ampere)
45
   */
46
  virtual double CalcTxCurrent (double txPowerDbm) const = 0;
47
48
  /**
49
   * Convert from dBm to Watts.
50
   *
51
   * \param dbm the power in dBm
52
   * \return the equivalent Watts for the given dBm
53
   */
54
  static double DbmToW (double dbm);
55
};
56
57
/**
58
 * \ingroup energy
59
 *
60
 * \brief a linear model of the Wifi transmit current
61
 *
62
 * This model assumes that the transmit current is a linear function
63
 * of the nominal transmit power used to send the frame.
64
 * In particular, the power absorbed during the transmission of a frame \f$ W_{tx} \f$
65
 * is given by the power absorbed by the power amplifier \f$ W_{pa} \f$ plus the power
66
 * absorbed by the RF subsystem. The latter is assumed to be the same as the power
67
 * absorbed in the IDLE state \f$ W_{idle} \f$.
68
 * 
69
 * The efficiency \f$ \eta \f$ of the power amplifier is given by 
70
 * \f$ \eta = \frac{P_{tx}}{W_{pa}} \f$, where \f$ P_{tx} \f$ is the output power, i.e.,
71
 * the nominal transmit power. Hence, \f$ W_{pa} = \frac{P_{tx}}{\eta} \f$
72
 * 
73
 * It turns out that \f$ W_{tx} = \frac{P_{tx}}{\eta} + W_{idle} \f$. By dividing both
74
 * sides by the supply voltage \f$ V \f$: \f$ I_{tx} = \frac{P_{tx}}{V \cdot \eta} + I_{idle} \f$,
75
 * where \f$ I_{tx} \f$ and \f$ I_{idle} \f$ are, respectively, the transmit current and
76
 * the idle current.
77
 * 
78
 * For more information, refer to:
79
 * Francesco Ivan Di Piazza, Stefano Mangione, and Ilenia Tinnirello.
80
 * "On the Effects of Transmit Power Control on the Energy Consumption of WiFi Network Cards",
81
 * Proceedings of ICST QShine 2009, pp. 463--475
82
 * 
83
 * If the tx current corresponding to a given nominal transmit power is known, the efficiency
84
 * of the power amplifier is given by the above formula:
85
 * \f$ \eta = \frac{P_{tx}}{(I_{tx}-I_{idle})\cdot V} \f$
86
 * 
87
 */
88
class LinearWifiTxCurrentModel : public WifiTxCurrentModel
89
{
90
public:
91
  static TypeId GetTypeId (void);
92
93
  LinearWifiTxCurrentModel ();
94
  virtual ~LinearWifiTxCurrentModel ();
95
  
96
  /**
97
   * \param eta (dimension-less)
98
   *
99
   * Set the power amplifier efficiency.
100
   */
101
  void SetEta (double eta);
102
103
  /**
104
   * \param voltage (Volts)
105
   *
106
   * Set the supply voltage.
107
   */
108
  void SetVoltage (double voltage);
109
110
  /**
111
   * \param idleCurrent (Ampere)
112
   *
113
   * Set the current in the IDLE state.
114
   */
115
  void SetIdleCurrent (double idleCurrent);
116
117
  /**
118
   * \return the power amplifier efficiency.
119
   */
120
  double GetEta (void) const;
121
122
  /**
123
   * \return the supply voltage.
124
   */
125
  double GetVoltage (void) const;
126
127
  /**
128
   * \return the current in the IDLE state.
129
   */
130
  double GetIdleCurrent (void) const;
131
132
  double CalcTxCurrent (double txPowerDbm) const;
133
134
private:
135
  double m_eta;
136
  double m_voltage;
137
  double m_idleCurrent;
138
};
139
140
} // namespace ns3
141
142
#endif /* WIFI_TX_CURRENT_MODEL_H */
(-)a/src/energy/test/basic-energy-model-test.cc (-393 lines)
 Lines 1-393    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2010 Network Security Lab, University of Washington, Seattle.
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: He Wu <mdzz@u.washington.edu>
19
 */
20
21
#include "ns3/basic-energy-source.h"
22
#include "ns3/wifi-radio-energy-model.h"
23
#include "ns3/basic-energy-source-helper.h"
24
#include "ns3/wifi-radio-energy-model-helper.h"
25
#include "ns3/energy-source-container.h"
26
#include "ns3/device-energy-model-container.h"
27
#include "ns3/log.h"
28
#include "ns3/test.h"
29
#include "ns3/node.h"
30
#include "ns3/simulator.h"
31
#include "ns3/double.h"
32
#include "ns3/config.h"
33
#include "ns3/string.h"
34
#include "ns3/yans-wifi-helper.h"
35
#include "ns3/nqos-wifi-mac-helper.h"
36
#include <cmath>
37
38
using namespace ns3;
39
40
NS_LOG_COMPONENT_DEFINE ("BasicEnergyModelTestSuite");
41
42
/**
43
 * Test case of update remaining energy for BasicEnergySource and
44
 * WifiRadioEnergyModel.
45
 */
46
class BasicEnergyUpdateTest : public TestCase
47
{
48
public:
49
  BasicEnergyUpdateTest ();
50
  virtual ~BasicEnergyUpdateTest ();
51
52
private:
53
  void DoRun (void);
54
55
  /**
56
   * \param state Radio state to switch to.
57
   * \return False if no error occurs.
58
   *
59
   * Runs simulation for a while, check if final state & remaining energy is
60
   * correctly updated.
61
   */
62
  bool StateSwitchTest (WifiPhy::State state);
63
64
private:
65
  double m_timeS;     // in seconds
66
  double m_tolerance; // tolerance for power estimation
67
68
  ObjectFactory m_energySource;
69
  ObjectFactory m_deviceEnergyModel;
70
};
71
72
BasicEnergyUpdateTest::BasicEnergyUpdateTest ()
73
  : TestCase ("Basic energy model update remaining energy test case")
74
{
75
  m_timeS = 15.5; // idle for 15 seconds before changing state
76
  m_tolerance = 1.0e-13;  //
77
}
78
79
BasicEnergyUpdateTest::~BasicEnergyUpdateTest ()
80
{
81
}
82
83
void
84
BasicEnergyUpdateTest::DoRun (void)
85
{
86
  // set types
87
  m_energySource.SetTypeId ("ns3::BasicEnergySource");
88
  m_deviceEnergyModel.SetTypeId ("ns3::WifiRadioEnergyModel");
89
90
  // run state switch tests
91
  NS_TEST_ASSERT_MSG_EQ (StateSwitchTest (WifiPhy::IDLE), false, "Problem with state switch test (WifiPhy idle).");
92
  NS_TEST_ASSERT_MSG_EQ (StateSwitchTest (WifiPhy::CCA_BUSY), false, "Problem with state switch test (WifiPhy cca busy).");
93
  NS_TEST_ASSERT_MSG_EQ (StateSwitchTest (WifiPhy::TX), false, "Problem with state switch test (WifiPhy tx).");
94
  NS_TEST_ASSERT_MSG_EQ (StateSwitchTest (WifiPhy::RX), false, "Problem with state switch test (WifiPhy rx).");
95
  NS_TEST_ASSERT_MSG_EQ (StateSwitchTest (WifiPhy::SWITCHING), false, "Problem with state switch test (WifiPhy switching).");
96
  NS_TEST_ASSERT_MSG_EQ (StateSwitchTest (WifiPhy::SLEEP), false, "Problem with state switch test (WifiPhy sleep).");
97
}
98
99
bool
100
BasicEnergyUpdateTest::StateSwitchTest (WifiPhy::State state)
101
{
102
  // create node
103
  Ptr<Node> node = CreateObject<Node> ();
104
105
  // create energy source
106
  Ptr<BasicEnergySource> source = m_energySource.Create<BasicEnergySource> ();
107
  // aggregate energy source to node
108
  node->AggregateObject (source);
109
110
  // create device energy model
111
  Ptr<WifiRadioEnergyModel> model =
112
    m_deviceEnergyModel.Create<WifiRadioEnergyModel> ();
113
  // set energy source pointer
114
  model->SetEnergySource (source);
115
  // add device energy model to model list in energy source
116
  source->AppendDeviceEnergyModel (model);
117
118
  // retrieve device energy model from energy source
119
  DeviceEnergyModelContainer models =
120
    source->FindDeviceEnergyModels ("ns3::WifiRadioEnergyModel");
121
  // check list
122
  NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL (false, (models.GetN () == 0), "Model list is empty!");
123
  // get pointer
124
  Ptr<WifiRadioEnergyModel> devModel =
125
    DynamicCast<WifiRadioEnergyModel> (models.Get (0));
126
  // check pointer
127
  NS_TEST_ASSERT_MSG_NE_RETURNS_BOOL (0, devModel, "NULL pointer to device model!");
128
129
  /*
130
   * The radio will stay IDLE for m_timeS seconds. Then it will switch into a
131
   * different state.
132
   */
133
134
  // schedule change of state
135
  Simulator::Schedule (Seconds (m_timeS),
136
                       &WifiRadioEnergyModel::ChangeState, devModel, state);
137
138
  // Calculate remaining energy at simulation stop time
139
  Simulator::Schedule (Seconds (m_timeS * 2), 
140
                       &BasicEnergySource::UpdateEnergySource, source);
141
142
  double timeDelta = 0.000000001; // 1 nanosecond
143
  // run simulation; stop just after last scheduled event
144
  Simulator::Stop (Seconds (m_timeS * 2 + timeDelta));
145
  Simulator::Run ();
146
147
  // energy = current * voltage * time
148
149
  // calculate idle power consumption
150
  double estRemainingEnergy = source->GetInitialEnergy ();
151
  double voltage = source->GetSupplyVoltage ();
152
  estRemainingEnergy -= devModel->GetIdleCurrentA () * voltage * m_timeS;
153
154
  /*
155
   * Manually calculate the number of periodic updates performed by the source.
156
   * This is to check if the periodic updates are performed correctly.
157
   */
158
  double actualTime = m_timeS;
159
  actualTime /= source->GetEnergyUpdateInterval ().GetSeconds ();
160
  actualTime = floor (actualTime); // rounding for update interval
161
  actualTime *= source->GetEnergyUpdateInterval ().GetSeconds ();
162
163
  // calculate new state power consumption
164
  double current = 0.0;
165
  switch (state)
166
    {
167
    case WifiPhy::IDLE:
168
      current = devModel->GetIdleCurrentA ();
169
      break;
170
    case WifiPhy::CCA_BUSY:
171
      current = devModel->GetCcaBusyCurrentA ();
172
      break;
173
    case WifiPhy::TX:
174
      current = devModel->GetTxCurrentA ();
175
      break;
176
    case WifiPhy::RX:
177
      current = devModel->GetRxCurrentA ();
178
      break;
179
    case WifiPhy::SWITCHING:
180
      current = devModel->GetSwitchingCurrentA ();
181
      break;
182
    case WifiPhy::SLEEP:
183
      current = devModel->GetSleepCurrentA ();
184
      break;
185
    default:
186
      NS_FATAL_ERROR ("Undefined radio state: " << state);
187
      break;
188
    }
189
  estRemainingEnergy -= current * voltage * m_timeS;
190
191
  // obtain remaining energy from source
192
  double remainingEnergy = source->GetRemainingEnergy ();
193
  NS_LOG_DEBUG ("Remaining energy is " << remainingEnergy);
194
  NS_LOG_DEBUG ("Estimated remaining energy is " << estRemainingEnergy);
195
  NS_LOG_DEBUG ("Difference is " << estRemainingEnergy - remainingEnergy);
196
  // check remaining energy
197
  NS_TEST_ASSERT_MSG_EQ_TOL_RETURNS_BOOL (remainingEnergy, estRemainingEnergy, m_tolerance,
198
                                          "Incorrect remaining energy!");
199
200
  // obtain radio state
201
  WifiPhy::State endState = devModel->GetCurrentState ();
202
  NS_LOG_DEBUG ("Radio state is " << endState);
203
  // check end state
204
  NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL (endState, state,  "Incorrect end state!");
205
  Simulator::Destroy ();
206
207
  return false; // no error
208
}
209
210
// -------------------------------------------------------------------------- //
211
212
/**
213
 * Test case of energy depletion handling for BasicEnergySource and
214
 * WifiRadioEnergyModel.
215
 */
216
class BasicEnergyDepletionTest : public TestCase
217
{
218
public:
219
  BasicEnergyDepletionTest ();
220
  virtual ~BasicEnergyDepletionTest ();
221
222
private:
223
  void DoRun (void);
224
225
  /**
226
   * Callback invoked when energy is drained from source.
227
   */
228
  void DepletionHandler (void);
229
230
  /**
231
   * \param simTimeS Simulation time, in seconds.
232
   * \param updateIntervalS Device model update interval, in seconds.
233
   * \return False if all is good.
234
   *
235
   * Runs simulation with specified simulation time and update interval.
236
   */
237
  bool DepletionTestCase (double simTimeS, double updateIntervalS);
238
239
private:
240
  int m_numOfNodes;         // number of nodes in simulation
241
  int m_callbackCount;      // counter for # of callbacks invoked
242
  double m_simTimeS;        // maximum simulation time, in seconds
243
  double m_timeStepS;       // simulation time step size, in seconds
244
  double m_updateIntervalS; // update interval of each device model
245
246
};
247
248
BasicEnergyDepletionTest::BasicEnergyDepletionTest ()
249
  : TestCase ("Basic energy model energy depletion test case")
250
{
251
  m_numOfNodes = 10;
252
  m_callbackCount = 0;
253
  m_simTimeS = 4.5;
254
  m_timeStepS = 0.5;
255
  m_updateIntervalS = 1.5;
256
}
257
258
BasicEnergyDepletionTest::~BasicEnergyDepletionTest ()
259
{
260
}
261
262
void
263
BasicEnergyDepletionTest::DoRun (void)
264
{
265
  /*
266
   * Run simulation with different simulation time and update interval.
267
   */
268
  for (double simTimeS = 0.0; simTimeS <= m_simTimeS; simTimeS += m_timeStepS)
269
    {
270
      for (double updateIntervalS = 0.5; updateIntervalS <= m_updateIntervalS;
271
           updateIntervalS += m_timeStepS)
272
        {
273
          NS_TEST_ASSERT_MSG_EQ (DepletionTestCase (simTimeS, updateIntervalS), false, "Depletion test case problem.");
274
          // reset callback count
275
          m_callbackCount = 0;
276
        }
277
    }
278
}
279
280
void
281
BasicEnergyDepletionTest::DepletionHandler (void)
282
{
283
  m_callbackCount++;
284
}
285
286
bool
287
BasicEnergyDepletionTest::DepletionTestCase (double simTimeS,
288
                                             double updateIntervalS)
289
{
290
  // create node
291
  NodeContainer c;
292
  c.Create (m_numOfNodes);
293
294
  std::string phyMode ("DsssRate1Mbps");
295
296
  // disable fragmentation for frames below 2200 bytes
297
  Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold",
298
                      StringValue ("2200"));
299
  // turn off RTS/CTS for frames below 2200 bytes
300
  Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold",
301
                      StringValue ("2200"));
302
  // Fix non-unicast data rate to be the same as that of unicast
303
  Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode",
304
                      StringValue (phyMode));
305
306
  // install YansWifiPhy
307
  WifiHelper wifi;
308
  wifi.SetStandard (WIFI_PHY_STANDARD_80211b);
309
310
  YansWifiPhyHelper wifiPhy =  YansWifiPhyHelper::Default ();
311
  /*
312
   * This is one parameter that matters when using FixedRssLossModel, set it to
313
   * zero; otherwise, gain will be added.
314
   */
315
  wifiPhy.Set ("RxGain", DoubleValue (0));
316
  // ns-3 supports RadioTap and Prism tracing extensions for 802.11b
317
  wifiPhy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO);
318
319
  YansWifiChannelHelper wifiChannel;
320
  wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
321
  wifiPhy.SetChannel (wifiChannel.Create ());
322
323
  // Add a non-QoS upper MAC, and disable rate control
324
  NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
325
  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
326
                                "DataMode", StringValue (phyMode),
327
                                "ControlMode", StringValue (phyMode));
328
  // Set it to ad-hoc mode
329
  wifiMac.SetType ("ns3::AdhocWifiMac");
330
  NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, c);
331
332
  /*
333
   * Create and install energy source and a single basic radio energy model on
334
   * the node using helpers.
335
   */
336
  // source helper
337
  BasicEnergySourceHelper basicSourceHelper;
338
  // set energy to 0 so that we deplete energy at the beginning of simulation
339
  basicSourceHelper.Set ("BasicEnergySourceInitialEnergyJ", DoubleValue (0.0));
340
  // set update interval
341
  basicSourceHelper.Set ("PeriodicEnergyUpdateInterval",
342
                         TimeValue (Seconds (updateIntervalS)));
343
  // install source
344
  EnergySourceContainer sources = basicSourceHelper.Install (c);
345
346
  // device energy model helper
347
  WifiRadioEnergyModelHelper radioEnergyHelper;
348
  // set energy depletion callback
349
  WifiRadioEnergyModel::WifiRadioEnergyDepletionCallback callback =
350
    MakeCallback (&BasicEnergyDepletionTest::DepletionHandler, this);
351
  radioEnergyHelper.SetDepletionCallback (callback);
352
  // install on node
353
  DeviceEnergyModelContainer deviceModels = radioEnergyHelper.Install (devices, sources);
354
355
  // run simulation
356
  Simulator::Stop (Seconds (simTimeS));
357
  Simulator::Run ();
358
  Simulator::Destroy ();
359
360
  NS_LOG_DEBUG ("Simulation time = " << simTimeS << "s");
361
  NS_LOG_DEBUG ("Update interval = " << updateIntervalS << "s");
362
  NS_LOG_DEBUG ("Expected callback count is " << m_numOfNodes);
363
  NS_LOG_DEBUG ("Actual callback count is " << m_callbackCount);
364
365
  // check result, call back should only be invoked once
366
  NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL (m_numOfNodes, m_callbackCount, "Not all callbacks are invoked!");
367
368
  return false;
369
}
370
371
// -------------------------------------------------------------------------- //
372
373
/**
374
 * Unit test suite for energy model. Although the test suite involves 2 modules
375
 * it is still considered a unit test. Because a DeviceEnergyModel cannot live
376
 * without an EnergySource.
377
 */
378
class BasicEnergyModelTestSuite : public TestSuite
379
{
380
public:
381
  BasicEnergyModelTestSuite ();
382
};
383
384
BasicEnergyModelTestSuite::BasicEnergyModelTestSuite ()
385
  : TestSuite ("basic-energy-model", UNIT)
386
{
387
  AddTestCase (new BasicEnergyUpdateTest, TestCase::QUICK);
388
  AddTestCase (new BasicEnergyDepletionTest, TestCase::QUICK);
389
}
390
391
// create an instance of the test suite
392
static BasicEnergyModelTestSuite g_energyModelTestSuite;
393
(-)a/src/energy/test/examples-to-run.py (-1 / +4 lines)
 Lines 7-13    Link Here 
7
#     (example_name, do_run, do_valgrind_run).
7
#     (example_name, do_run, do_valgrind_run).
8
#
8
#
9
# See test.py for more information.
9
# See test.py for more information.
10
cpp_examples = []
10
cpp_examples = [
11
    ("li-ion-energy-source", "True", "True"),
12
    ("rv-battery-model-test", "True", "True"),
13
]
11
14
12
# A list of Python examples to run in order to ensure that they remain
15
# A list of Python examples to run in order to ensure that they remain
13
# runnable over time.  Each tuple in the list contains
16
# runnable over time.  Each tuple in the list contains
(-)a/src/energy/test/li-ion-energy-source-test.cc (-1 lines)
 Lines 37-43    Link Here 
37
37
38
  void DoRun (void);
38
  void DoRun (void);
39
39
40
  double m_simTime;
41
  Ptr<Node> m_node;
40
  Ptr<Node> m_node;
42
};
41
};
43
42
(-)a/src/energy/wscript (-9 / +1 lines)
 Lines 1-9    Link Here 
1
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
1
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
2
2
3
def build(bld):
3
def build(bld):
4
    obj = bld.create_ns3_module('energy', ['wifi'])
4
    obj = bld.create_ns3_module('energy', ['network'])
5
    obj.source = [
5
    obj.source = [
6
        'model/wifi-radio-energy-model.cc',
7
        'model/energy-source.cc',
6
        'model/energy-source.cc',
8
        'model/basic-energy-source.cc',
7
        'model/basic-energy-source.cc',
9
        'model/li-ion-energy-source.cc',
8
        'model/li-ion-energy-source.cc',
 Lines 13-23    Link Here 
13
        'model/simple-device-energy-model.cc',
12
        'model/simple-device-energy-model.cc',
14
        'model/energy-harvester.cc',
13
        'model/energy-harvester.cc',
15
        'model/basic-energy-harvester.cc',
14
        'model/basic-energy-harvester.cc',
16
        'model/wifi-tx-current-model.cc',
17
        'helper/energy-source-container.cc',
15
        'helper/energy-source-container.cc',
18
        'helper/energy-model-helper.cc',
16
        'helper/energy-model-helper.cc',
19
        'helper/basic-energy-source-helper.cc',
17
        'helper/basic-energy-source-helper.cc',
20
        'helper/wifi-radio-energy-model-helper.cc',
21
        'helper/rv-battery-model-helper.cc',
18
        'helper/rv-battery-model-helper.cc',
22
        'helper/energy-harvester-container.cc',
19
        'helper/energy-harvester-container.cc',
23
        'helper/energy-harvester-helper.cc',
20
        'helper/energy-harvester-helper.cc',
 Lines 26-33    Link Here 
26
23
27
    obj_test = bld.create_ns3_module_test_library('energy')
24
    obj_test = bld.create_ns3_module_test_library('energy')
28
    obj_test.source = [
25
    obj_test.source = [
29
        'test/basic-energy-model-test.cc',
30
        'test/rv-battery-model-test.cc',
31
        'test/li-ion-energy-source-test.cc',
26
        'test/li-ion-energy-source-test.cc',
32
        'test/basic-energy-harvester-test.cc',
27
        'test/basic-energy-harvester-test.cc',
33
        ]
28
        ]
 Lines 35-41    Link Here 
35
    headers = bld(features='ns3header')
30
    headers = bld(features='ns3header')
36
    headers.module = 'energy'
31
    headers.module = 'energy'
37
    headers.source = [
32
    headers.source = [
38
        'model/wifi-radio-energy-model.h',
39
        'model/energy-source.h',
33
        'model/energy-source.h',
40
        'model/basic-energy-source.h',
34
        'model/basic-energy-source.h',
41
        'model/li-ion-energy-source.h',
35
        'model/li-ion-energy-source.h',
 Lines 45-55    Link Here 
45
        'model/simple-device-energy-model.h',
39
        'model/simple-device-energy-model.h',
46
        'model/energy-harvester.h',
40
        'model/energy-harvester.h',
47
        'model/basic-energy-harvester.h',
41
        'model/basic-energy-harvester.h',
48
        'model/wifi-tx-current-model.h',
49
        'helper/energy-source-container.h',
42
        'helper/energy-source-container.h',
50
        'helper/energy-model-helper.h',
43
        'helper/energy-model-helper.h',
51
        'helper/basic-energy-source-helper.h',
44
        'helper/basic-energy-source-helper.h',
52
        'helper/wifi-radio-energy-model-helper.h',
53
        'helper/rv-battery-model-helper.h',
45
        'helper/rv-battery-model-helper.h',
54
        'helper/energy-harvester-container.h',
46
        'helper/energy-harvester-container.h',
55
        'helper/energy-harvester-helper.h',
47
        'helper/energy-harvester-helper.h',
(-)a/src/uan/wscript (-1 / +1 lines)
 Lines 1-7    Link Here 
1
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
1
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
2
2
3
def build(bld):
3
def build(bld):
4
    module = bld.create_ns3_module('uan', ['network', 'energy'])
4
    module = bld.create_ns3_module('uan', ['network', 'energy', 'mobility'])
5
    module.source = [
5
    module.source = [
6
        'model/uan-channel.cc',
6
        'model/uan-channel.cc',
7
        'model/uan-phy-gen.cc',
7
        'model/uan-phy-gen.cc',
(-)a/src/wifi/helper/wifi-radio-energy-model-helper.cc (+143 lines)
Line 0    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2010 Network Security Lab, University of Washington, Seattle.
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
 * Authors: Sidharth Nabar <snabar@uw.edu>, He Wu <mdzz@u.washington.edu>
19
 */
20
21
#include "wifi-radio-energy-model-helper.h"
22
#include "ns3/basic-energy-source-helper.h"
23
#include "ns3/wifi-phy.h"
24
#include "ns3/wifi-net-device.h"
25
#include "ns3/config.h"
26
#include "ns3/names.h"
27
#include "ns3/wifi-tx-current-model.h"
28
29
namespace ns3 {
30
31
WifiRadioEnergyModelHelper::WifiRadioEnergyModelHelper ()
32
{
33
  m_radioEnergy.SetTypeId ("ns3::WifiRadioEnergyModel");
34
  m_depletionCallback.Nullify ();
35
  m_rechargedCallback.Nullify ();
36
}
37
38
WifiRadioEnergyModelHelper::~WifiRadioEnergyModelHelper ()
39
{
40
}
41
42
void
43
WifiRadioEnergyModelHelper::Set (std::string name, const AttributeValue &v)
44
{
45
  m_radioEnergy.Set (name, v);
46
}
47
48
void
49
WifiRadioEnergyModelHelper::SetDepletionCallback (
50
  WifiRadioEnergyModel::WifiRadioEnergyDepletionCallback callback)
51
{
52
  m_depletionCallback = callback;
53
}
54
55
void
56
WifiRadioEnergyModelHelper::SetRechargedCallback (
57
  WifiRadioEnergyModel::WifiRadioEnergyRechargedCallback callback)
58
{
59
  m_rechargedCallback = callback;
60
}
61
62
void
63
WifiRadioEnergyModelHelper::SetTxCurrentModel (std::string name,
64
                                               std::string n0, const AttributeValue& v0,
65
                                               std::string n1, const AttributeValue& v1,
66
                                               std::string n2, const AttributeValue& v2,
67
                                               std::string n3, const AttributeValue& v3,
68
                                               std::string n4, const AttributeValue& v4,
69
                                               std::string n5, const AttributeValue& v5,
70
                                               std::string n6, const AttributeValue& v6,
71
                                               std::string n7, const AttributeValue& v7)
72
{
73
  ObjectFactory factory;
74
  factory.SetTypeId (name);
75
  factory.Set (n0, v0);
76
  factory.Set (n1, v1);
77
  factory.Set (n2, v2);
78
  factory.Set (n3, v3);
79
  factory.Set (n4, v4);
80
  factory.Set (n5, v5);
81
  factory.Set (n6, v6);
82
  factory.Set (n7, v7);
83
  m_txCurrentModel = factory;
84
}
85
86
87
/*
88
 * Private function starts here.
89
 */
90
91
Ptr<DeviceEnergyModel>
92
WifiRadioEnergyModelHelper::DoInstall (Ptr<NetDevice> device,
93
                                       Ptr<EnergySource> source) const
94
{
95
  NS_ASSERT (device != NULL);
96
  NS_ASSERT (source != NULL);
97
  // check if device is WifiNetDevice
98
  std::string deviceName = device->GetInstanceTypeId ().GetName ();
99
  if (deviceName.compare ("ns3::WifiNetDevice") != 0)
100
    {
101
      NS_FATAL_ERROR ("NetDevice type is not WifiNetDevice!");
102
    }
103
  Ptr<Node> node = device->GetNode ();
104
  Ptr<WifiRadioEnergyModel> model = m_radioEnergy.Create ()->GetObject<WifiRadioEnergyModel> ();
105
  NS_ASSERT (model != NULL);
106
  // set energy source pointer
107
  model->SetEnergySource (source);
108
  // set energy depletion callback
109
  // if none is specified, make a callback to WifiPhy::SetSleepMode
110
  Ptr<WifiNetDevice> wifiDevice = DynamicCast<WifiNetDevice> (device);
111
  Ptr<WifiPhy> wifiPhy = wifiDevice->GetPhy ();
112
  if (m_depletionCallback.IsNull ())
113
    {
114
      model->SetEnergyDepletionCallback (MakeCallback (&WifiPhy::SetSleepMode, wifiPhy));
115
    }
116
  else
117
    {
118
      model->SetEnergyDepletionCallback (m_depletionCallback);
119
    }
120
  // set energy recharged callback
121
  // if none is specified, make a callback to WifiPhy::ResumeFromSleep
122
  if (m_rechargedCallback.IsNull ())
123
    {
124
      model->SetEnergyRechargedCallback (MakeCallback (&WifiPhy::ResumeFromSleep, wifiPhy));
125
    }
126
  else
127
    {
128
      model->SetEnergyRechargedCallback (m_rechargedCallback);
129
    }
130
  // add model to device model list in energy source
131
  source->AppendDeviceEnergyModel (model);
132
  // create and register energy model phy listener
133
  wifiPhy->RegisterListener (model->GetPhyListener ());
134
  //
135
  if (m_txCurrentModel.GetTypeId ().GetUid ())
136
    {
137
      Ptr<WifiTxCurrentModel> txcurrent = m_txCurrentModel.Create<WifiTxCurrentModel> ();
138
      model->SetTxCurrentModel (txcurrent);
139
    }
140
  return model;
141
}
142
143
} // namespace ns3
(-)a/src/wifi/helper/wifi-radio-energy-model-helper.h (+124 lines)
Line 0    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright (c) 2010 Network Security Lab, University of Washington, Seattle.
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: Sidharth Nabar <snabar@uw.edu>, He Wu <mdzz@u.washington.edu>
19
*/
20
21
#ifndef WIFI_RADIO_ENERGY_MODEL_HELPER_H
22
#define WIFI_RADIO_ENERGY_MODEL_HELPER_H
23
24
#include "ns3/energy-model-helper.h"
25
#include "ns3/wifi-radio-energy-model.h"
26
27
namespace ns3 {
28
29
/**
30
 * \ingroup energy
31
 * \brief Assign WifiRadioEnergyModel to wifi devices.
32
 *
33
 * This installer installs WifiRadioEnergyModel for only WifiNetDevice objects.
34
 *
35
 */
36
class WifiRadioEnergyModelHelper : public DeviceEnergyModelHelper
37
{
38
public:
39
  /**
40
   * Construct a helper which is used to add a radio energy model to a node
41
   */
42
  WifiRadioEnergyModelHelper ();
43
44
  /**
45
   * Destroy a RadioEnergy Helper
46
   */
47
  ~WifiRadioEnergyModelHelper ();
48
49
  /**
50
   * \param name the name of the attribute to set
51
   * \param v the value of the attribute
52
   *
53
   * Sets an attribute of the underlying PHY object.
54
   */
55
  void Set (std::string name, const AttributeValue &v);
56
57
  /**
58
   * \param callback Callback function for energy depletion handling.
59
   *
60
   * Sets the callback to be invoked when energy is depleted.
61
   */
62
  void SetDepletionCallback (
63
    WifiRadioEnergyModel::WifiRadioEnergyDepletionCallback callback);
64
65
  /**
66
   * \param callback Callback function for energy recharged handling.
67
   *
68
   * Sets the callback to be invoked when energy is recharged.
69
   */
70
  void SetRechargedCallback (
71
    WifiRadioEnergyModel::WifiRadioEnergyRechargedCallback callback);
72
73
  /**
74
   * \param name the name of the model to set
75
   * \param n0 the name of the attribute to set
76
   * \param v0 the value of the attribute to set
77
   * \param n1 the name of the attribute to set
78
   * \param v1 the value of the attribute to set
79
   * \param n2 the name of the attribute to set
80
   * \param v2 the value of the attribute to set
81
   * \param n3 the name of the attribute to set
82
   * \param v3 the value of the attribute to set
83
   * \param n4 the name of the attribute to set
84
   * \param v4 the value of the attribute to set
85
   * \param n5 the name of the attribute to set
86
   * \param v5 the value of the attribute to set
87
   * \param n6 the name of the attribute to set
88
   * \param v6 the value of the attribute to set
89
   * \param n7 the name of the attribute to set
90
   * \param v7 the value of the attribute to set
91
   *
92
   * Configure a propagation delay for this channel.
93
   */
94
  void SetTxCurrentModel (std::string name,
95
                          std::string n0 = "", const AttributeValue &v0 = EmptyAttributeValue (),
96
                          std::string n1 = "", const AttributeValue &v1 = EmptyAttributeValue (),
97
                          std::string n2 = "", const AttributeValue &v2 = EmptyAttributeValue (),
98
                          std::string n3 = "", const AttributeValue &v3 = EmptyAttributeValue (),
99
                          std::string n4 = "", const AttributeValue &v4 = EmptyAttributeValue (),
100
                          std::string n5 = "", const AttributeValue &v5 = EmptyAttributeValue (),
101
                          std::string n6 = "", const AttributeValue &v6 = EmptyAttributeValue (),
102
                          std::string n7 = "", const AttributeValue &v7 = EmptyAttributeValue ());
103
104
private:
105
  /**
106
   * \param device Pointer to the NetDevice to install DeviceEnergyModel.
107
   * \param source Pointer to EnergySource to install.
108
   *
109
   * Implements DeviceEnergyModel::Install.
110
   */
111
  virtual Ptr<DeviceEnergyModel> DoInstall (Ptr<NetDevice> device,
112
                                            Ptr<EnergySource> source) const;
113
114
private:
115
  ObjectFactory m_radioEnergy;
116
  WifiRadioEnergyModel::WifiRadioEnergyDepletionCallback m_depletionCallback;
117
  WifiRadioEnergyModel::WifiRadioEnergyRechargedCallback m_rechargedCallback;
118
  ObjectFactory m_txCurrentModel;
119
120
};
121
122
} // namespace ns3
123
124
#endif /* WIFI_RADIO_ENERGY_MODEL_HELPER_H */
(-)a/src/wifi/model/wifi-radio-energy-model.cc (+572 lines)
Line 0    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2010 Network Security Lab, University of Washington, Seattle.
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: Sidharth Nabar <snabar@uw.edu>, He Wu <mdzz@u.washington.edu>
19
 */
20
21
#include "ns3/log.h"
22
#include "ns3/double.h"
23
#include "ns3/simulator.h"
24
#include "ns3/trace-source-accessor.h"
25
#include "ns3/pointer.h"
26
#include "ns3/energy-source.h"
27
#include "wifi-radio-energy-model.h"
28
#include "wifi-tx-current-model.h"
29
30
namespace ns3 {
31
32
NS_LOG_COMPONENT_DEFINE ("WifiRadioEnergyModel");
33
34
NS_OBJECT_ENSURE_REGISTERED (WifiRadioEnergyModel);
35
36
TypeId
37
WifiRadioEnergyModel::GetTypeId (void)
38
{
39
  static TypeId tid = TypeId ("ns3::WifiRadioEnergyModel")
40
    .SetParent<DeviceEnergyModel> ()
41
    .SetGroupName ("Energy")
42
    .AddConstructor<WifiRadioEnergyModel> ()
43
    .AddAttribute ("IdleCurrentA",
44
                   "The default radio Idle current in Ampere.",
45
                   DoubleValue (0.273),  // idle mode = 273mA
46
                   MakeDoubleAccessor (&WifiRadioEnergyModel::SetIdleCurrentA,
47
                                       &WifiRadioEnergyModel::GetIdleCurrentA),
48
                   MakeDoubleChecker<double> ())
49
    .AddAttribute ("CcaBusyCurrentA",
50
                   "The default radio CCA Busy State current in Ampere.",
51
                   DoubleValue (0.273),  // default to be the same as idle mode
52
                   MakeDoubleAccessor (&WifiRadioEnergyModel::SetCcaBusyCurrentA,
53
                                       &WifiRadioEnergyModel::GetCcaBusyCurrentA),
54
                   MakeDoubleChecker<double> ())
55
    .AddAttribute ("TxCurrentA",
56
                   "The radio Tx current in Ampere.",
57
                   DoubleValue (0.380),    // transmit at 0dBm = 380mA
58
                   MakeDoubleAccessor (&WifiRadioEnergyModel::SetTxCurrentA,
59
                                       &WifiRadioEnergyModel::GetTxCurrentA),
60
                   MakeDoubleChecker<double> ())
61
    .AddAttribute ("RxCurrentA",
62
                   "The radio Rx current in Ampere.",
63
                   DoubleValue (0.313),    // receive mode = 313mA
64
                   MakeDoubleAccessor (&WifiRadioEnergyModel::SetRxCurrentA,
65
                                       &WifiRadioEnergyModel::GetRxCurrentA),
66
                   MakeDoubleChecker<double> ())
67
    .AddAttribute ("SwitchingCurrentA",
68
                   "The default radio Channel Switch current in Ampere.",
69
                   DoubleValue (0.273),  // default to be the same as idle mode
70
                   MakeDoubleAccessor (&WifiRadioEnergyModel::SetSwitchingCurrentA,
71
                                       &WifiRadioEnergyModel::GetSwitchingCurrentA),
72
                   MakeDoubleChecker<double> ())
73
    .AddAttribute ("SleepCurrentA",
74
                   "The radio Sleep current in Ampere.",
75
                   DoubleValue (0.033),  // sleep mode = 33mA
76
                   MakeDoubleAccessor (&WifiRadioEnergyModel::SetSleepCurrentA,
77
                                       &WifiRadioEnergyModel::GetSleepCurrentA),
78
                   MakeDoubleChecker<double> ())
79
    .AddAttribute ("TxCurrentModel", "A pointer to the attached tx current model.",
80
                   PointerValue (),
81
                   MakePointerAccessor (&WifiRadioEnergyModel::m_txCurrentModel),
82
                   MakePointerChecker<WifiTxCurrentModel> ())
83
    .AddTraceSource ("TotalEnergyConsumption",
84
                     "Total energy consumption of the radio device.",
85
                     MakeTraceSourceAccessor (&WifiRadioEnergyModel::m_totalEnergyConsumption),
86
                     "ns3::TracedValue::DoubleCallback")
87
  ; 
88
  return tid;
89
}
90
91
WifiRadioEnergyModel::WifiRadioEnergyModel ()
92
{
93
  NS_LOG_FUNCTION (this);
94
  m_currentState = WifiPhy::IDLE;  // initially IDLE
95
  m_lastUpdateTime = Seconds (0.0);
96
  m_nPendingChangeState = 0;
97
  m_isSupersededChangeState = false;
98
  m_energyDepletionCallback.Nullify ();
99
  m_source = NULL;
100
  // set callback for WifiPhy listener
101
  m_listener = new WifiRadioEnergyModelPhyListener;
102
  m_listener->SetChangeStateCallback (MakeCallback (&DeviceEnergyModel::ChangeState, this));
103
  // set callback for updating the tx current
104
  m_listener->SetUpdateTxCurrentCallback (MakeCallback (&WifiRadioEnergyModel::SetTxCurrentFromModel, this));
105
}
106
107
WifiRadioEnergyModel::~WifiRadioEnergyModel ()
108
{
109
  NS_LOG_FUNCTION (this);
110
  delete m_listener;
111
}
112
113
void
114
WifiRadioEnergyModel::SetEnergySource (Ptr<EnergySource> source)
115
{
116
  NS_LOG_FUNCTION (this << source);
117
  NS_ASSERT (source != NULL);
118
  m_source = source;
119
}
120
121
double
122
WifiRadioEnergyModel::GetTotalEnergyConsumption (void) const
123
{
124
  NS_LOG_FUNCTION (this);
125
  return m_totalEnergyConsumption;
126
}
127
128
double
129
WifiRadioEnergyModel::GetIdleCurrentA (void) const
130
{
131
  NS_LOG_FUNCTION (this);
132
  return m_idleCurrentA;
133
}
134
135
void
136
WifiRadioEnergyModel::SetIdleCurrentA (double idleCurrentA)
137
{
138
  NS_LOG_FUNCTION (this << idleCurrentA);
139
  m_idleCurrentA = idleCurrentA;
140
}
141
142
double
143
WifiRadioEnergyModel::GetCcaBusyCurrentA (void) const
144
{
145
  NS_LOG_FUNCTION (this);
146
  return m_ccaBusyCurrentA;
147
}
148
149
void
150
WifiRadioEnergyModel::SetCcaBusyCurrentA (double CcaBusyCurrentA)
151
{
152
  NS_LOG_FUNCTION (this << CcaBusyCurrentA);
153
  m_ccaBusyCurrentA = CcaBusyCurrentA;
154
}
155
156
double
157
WifiRadioEnergyModel::GetTxCurrentA (void) const
158
{
159
  NS_LOG_FUNCTION (this);
160
  return m_txCurrentA;
161
}
162
163
void
164
WifiRadioEnergyModel::SetTxCurrentA (double txCurrentA)
165
{
166
  NS_LOG_FUNCTION (this << txCurrentA);
167
  m_txCurrentA = txCurrentA;
168
}
169
170
double
171
WifiRadioEnergyModel::GetRxCurrentA (void) const
172
{
173
  NS_LOG_FUNCTION (this);
174
  return m_rxCurrentA;
175
}
176
177
void
178
WifiRadioEnergyModel::SetRxCurrentA (double rxCurrentA)
179
{
180
  NS_LOG_FUNCTION (this << rxCurrentA);
181
  m_rxCurrentA = rxCurrentA;
182
}
183
184
double
185
WifiRadioEnergyModel::GetSwitchingCurrentA (void) const
186
{
187
  NS_LOG_FUNCTION (this);
188
  return m_switchingCurrentA;
189
}
190
191
void
192
WifiRadioEnergyModel::SetSwitchingCurrentA (double switchingCurrentA)
193
{
194
  NS_LOG_FUNCTION (this << switchingCurrentA);
195
  m_switchingCurrentA = switchingCurrentA;
196
}
197
198
double
199
WifiRadioEnergyModel::GetSleepCurrentA (void) const
200
{
201
  NS_LOG_FUNCTION (this);
202
  return m_sleepCurrentA;
203
}
204
205
void
206
WifiRadioEnergyModel::SetSleepCurrentA (double sleepCurrentA)
207
{
208
  NS_LOG_FUNCTION (this << sleepCurrentA);
209
  m_sleepCurrentA = sleepCurrentA;
210
}
211
212
WifiPhy::State
213
WifiRadioEnergyModel::GetCurrentState (void) const
214
{
215
  NS_LOG_FUNCTION (this);
216
  return m_currentState;
217
}
218
219
void
220
WifiRadioEnergyModel::SetEnergyDepletionCallback (
221
  WifiRadioEnergyDepletionCallback callback)
222
{
223
  NS_LOG_FUNCTION (this);
224
  if (callback.IsNull ())
225
    {
226
      NS_LOG_DEBUG ("WifiRadioEnergyModel:Setting NULL energy depletion callback!");
227
    }
228
  m_energyDepletionCallback = callback;
229
}
230
231
void
232
WifiRadioEnergyModel::SetEnergyRechargedCallback (
233
  WifiRadioEnergyRechargedCallback callback)
234
{
235
  NS_LOG_FUNCTION (this);
236
  if (callback.IsNull ())
237
    {
238
      NS_LOG_DEBUG ("WifiRadioEnergyModel:Setting NULL energy recharged callback!");
239
    }
240
  m_energyRechargedCallback = callback;
241
}
242
243
void
244
WifiRadioEnergyModel::SetTxCurrentModel (Ptr<WifiTxCurrentModel> model)
245
{
246
  m_txCurrentModel = model;
247
}
248
249
void
250
WifiRadioEnergyModel::SetTxCurrentFromModel (double txPowerDbm)
251
{
252
  if (m_txCurrentModel)
253
    {
254
      m_txCurrentA = m_txCurrentModel->CalcTxCurrent (txPowerDbm);
255
    }
256
}
257
258
void
259
WifiRadioEnergyModel::ChangeState (int newState)
260
{
261
  NS_LOG_FUNCTION (this << newState);
262
263
  Time duration = Simulator::Now () - m_lastUpdateTime;
264
  NS_ASSERT (duration.GetNanoSeconds () >= 0); // check if duration is valid
265
266
  // energy to decrease = current * voltage * time
267
  double energyToDecrease = 0.0;
268
  double supplyVoltage = m_source->GetSupplyVoltage ();
269
  switch (m_currentState)
270
    {
271
    case WifiPhy::IDLE:
272
      energyToDecrease = duration.GetSeconds () * m_idleCurrentA * supplyVoltage;
273
      break;
274
    case WifiPhy::CCA_BUSY:
275
      energyToDecrease = duration.GetSeconds () * m_ccaBusyCurrentA * supplyVoltage;
276
      break;
277
    case WifiPhy::TX:
278
      energyToDecrease = duration.GetSeconds () * m_txCurrentA * supplyVoltage;
279
      break;
280
    case WifiPhy::RX:
281
      energyToDecrease = duration.GetSeconds () * m_rxCurrentA * supplyVoltage;
282
      break;
283
    case WifiPhy::SWITCHING:
284
      energyToDecrease = duration.GetSeconds () * m_switchingCurrentA * supplyVoltage;
285
      break;
286
    case WifiPhy::SLEEP:
287
      energyToDecrease = duration.GetSeconds () * m_sleepCurrentA * supplyVoltage;
288
      break;
289
    default:
290
      NS_FATAL_ERROR ("WifiRadioEnergyModel:Undefined radio state: " << m_currentState);
291
    }
292
293
  // update total energy consumption
294
  m_totalEnergyConsumption += energyToDecrease;
295
296
  // update last update time stamp
297
  m_lastUpdateTime = Simulator::Now ();
298
299
  m_nPendingChangeState++;
300
301
  // notify energy source
302
  m_source->UpdateEnergySource ();
303
304
  // in case the energy source is found to be depleted during the last update, a callback might be
305
  // invoked that might cause a change in the Wifi PHY state (e.g., the PHY is put into SLEEP mode).
306
  // This in turn causes a new call to this member function, with the consequence that the previous
307
  // instance is resumed after the termination of the new instance. In particular, the state set
308
  // by the previous instance is erroneously the final state stored in m_currentState. The check below
309
  // ensures that previous instances do not change m_currentState.
310
311
  if (!m_isSupersededChangeState)
312
    {
313
      // update current state & last update time stamp
314
      SetWifiRadioState ((WifiPhy::State) newState);
315
316
      // some debug message
317
      NS_LOG_DEBUG ("WifiRadioEnergyModel:Total energy consumption is " <<
318
                    m_totalEnergyConsumption << "J");
319
    }
320
321
  m_isSupersededChangeState = (m_nPendingChangeState > 1);
322
323
  m_nPendingChangeState--;
324
}
325
326
void
327
WifiRadioEnergyModel::HandleEnergyDepletion (void)
328
{
329
  NS_LOG_FUNCTION (this);
330
  NS_LOG_DEBUG ("WifiRadioEnergyModel:Energy is depleted!");
331
  // invoke energy depletion callback, if set.
332
  if (!m_energyDepletionCallback.IsNull ())
333
    {
334
      m_energyDepletionCallback ();
335
    }
336
}
337
338
void
339
WifiRadioEnergyModel::HandleEnergyRecharged (void)
340
{
341
  NS_LOG_FUNCTION (this);
342
  NS_LOG_DEBUG ("WifiRadioEnergyModel:Energy is recharged!");
343
  // invoke energy recharged callback, if set.
344
  if (!m_energyRechargedCallback.IsNull ())
345
    {
346
      m_energyRechargedCallback ();
347
    }
348
}
349
350
WifiRadioEnergyModelPhyListener *
351
WifiRadioEnergyModel::GetPhyListener (void)
352
{
353
  NS_LOG_FUNCTION (this);
354
  return m_listener;
355
}
356
357
/*
358
 * Private functions start here.
359
 */
360
361
void
362
WifiRadioEnergyModel::DoDispose (void)
363
{
364
  NS_LOG_FUNCTION (this);
365
  m_source = NULL;
366
  m_energyDepletionCallback.Nullify ();
367
}
368
369
double
370
WifiRadioEnergyModel::DoGetCurrentA (void) const
371
{
372
  NS_LOG_FUNCTION (this);
373
  switch (m_currentState)
374
    {
375
    case WifiPhy::IDLE:
376
      return m_idleCurrentA;
377
    case WifiPhy::CCA_BUSY:
378
      return m_ccaBusyCurrentA;
379
    case WifiPhy::TX:
380
      return m_txCurrentA;
381
    case WifiPhy::RX:
382
      return m_rxCurrentA;
383
    case WifiPhy::SWITCHING:
384
      return m_switchingCurrentA;
385
    case WifiPhy::SLEEP:
386
      return m_sleepCurrentA;
387
    default:
388
      NS_FATAL_ERROR ("WifiRadioEnergyModel:Undefined radio state:" << m_currentState);
389
    }
390
}
391
392
void
393
WifiRadioEnergyModel::SetWifiRadioState (const WifiPhy::State state)
394
{
395
  NS_LOG_FUNCTION (this << state);
396
  m_currentState = state;
397
  std::string stateName;
398
  switch (state)
399
    {
400
    case WifiPhy::IDLE:
401
      stateName = "IDLE";
402
      break;
403
    case WifiPhy::CCA_BUSY:
404
      stateName = "CCA_BUSY";
405
      break;
406
    case WifiPhy::TX:
407
      stateName = "TX";
408
      break;
409
    case WifiPhy::RX:
410
      stateName = "RX";
411
      break;
412
    case WifiPhy::SWITCHING:
413
      stateName = "SWITCHING";
414
      break;
415
    case WifiPhy::SLEEP:
416
      stateName = "SLEEP";
417
      break;
418
    }
419
  NS_LOG_DEBUG ("WifiRadioEnergyModel:Switching to state: " << stateName <<
420
                " at time = " << Simulator::Now ());
421
}
422
423
// -------------------------------------------------------------------------- //
424
425
WifiRadioEnergyModelPhyListener::WifiRadioEnergyModelPhyListener ()
426
{
427
  NS_LOG_FUNCTION (this);
428
  m_changeStateCallback.Nullify ();
429
  m_updateTxCurrentCallback.Nullify ();
430
}
431
432
WifiRadioEnergyModelPhyListener::~WifiRadioEnergyModelPhyListener ()
433
{
434
  NS_LOG_FUNCTION (this);
435
}
436
437
void
438
WifiRadioEnergyModelPhyListener::SetChangeStateCallback (DeviceEnergyModel::ChangeStateCallback callback)
439
{
440
  NS_LOG_FUNCTION (this << &callback);
441
  NS_ASSERT (!callback.IsNull ());
442
  m_changeStateCallback = callback;
443
}
444
445
void
446
WifiRadioEnergyModelPhyListener::SetUpdateTxCurrentCallback (UpdateTxCurrentCallback callback)
447
{
448
  NS_LOG_FUNCTION (this << &callback);
449
  NS_ASSERT (!callback.IsNull ());
450
  m_updateTxCurrentCallback = callback;
451
}
452
453
void
454
WifiRadioEnergyModelPhyListener::NotifyRxStart (Time duration)
455
{
456
  NS_LOG_FUNCTION (this << duration);
457
  if (m_changeStateCallback.IsNull ())
458
    {
459
      NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
460
    }
461
  m_changeStateCallback (WifiPhy::RX);
462
  m_switchToIdleEvent.Cancel ();
463
}
464
465
void
466
WifiRadioEnergyModelPhyListener::NotifyRxEndOk (void)
467
{
468
  NS_LOG_FUNCTION (this);
469
  if (m_changeStateCallback.IsNull ())
470
    {
471
      NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
472
    }
473
  m_changeStateCallback (WifiPhy::IDLE);
474
}
475
476
void
477
WifiRadioEnergyModelPhyListener::NotifyRxEndError (void)
478
{
479
  NS_LOG_FUNCTION (this);
480
  if (m_changeStateCallback.IsNull ())
481
    {
482
      NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
483
    }
484
  m_changeStateCallback (WifiPhy::IDLE);
485
}
486
487
void
488
WifiRadioEnergyModelPhyListener::NotifyTxStart (Time duration, double txPowerDbm)
489
{
490
  NS_LOG_FUNCTION (this << duration << txPowerDbm);
491
  if (m_updateTxCurrentCallback.IsNull ())
492
    {
493
      NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Update tx current callback not set!");
494
    }
495
  m_updateTxCurrentCallback (txPowerDbm);
496
  if (m_changeStateCallback.IsNull ())
497
    {
498
      NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
499
    }
500
  m_changeStateCallback (WifiPhy::TX);
501
  // schedule changing state back to IDLE after TX duration
502
  m_switchToIdleEvent.Cancel ();
503
  m_switchToIdleEvent = Simulator::Schedule (duration, &WifiRadioEnergyModelPhyListener::SwitchToIdle, this);
504
}
505
506
void
507
WifiRadioEnergyModelPhyListener::NotifyMaybeCcaBusyStart (Time duration)
508
{
509
  NS_LOG_FUNCTION (this << duration);
510
  if (m_changeStateCallback.IsNull ())
511
    {
512
      NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
513
    }
514
  m_changeStateCallback (WifiPhy::CCA_BUSY);
515
  // schedule changing state back to IDLE after CCA_BUSY duration
516
  m_switchToIdleEvent.Cancel ();
517
  m_switchToIdleEvent = Simulator::Schedule (duration, &WifiRadioEnergyModelPhyListener::SwitchToIdle, this);
518
}
519
520
void
521
WifiRadioEnergyModelPhyListener::NotifySwitchingStart (Time duration)
522
{
523
  NS_LOG_FUNCTION (this << duration);
524
  if (m_changeStateCallback.IsNull ())
525
    {
526
      NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
527
    }
528
  m_changeStateCallback (WifiPhy::SWITCHING);
529
  // schedule changing state back to IDLE after CCA_BUSY duration
530
  m_switchToIdleEvent.Cancel ();
531
  m_switchToIdleEvent = Simulator::Schedule (duration, &WifiRadioEnergyModelPhyListener::SwitchToIdle, this);
532
}
533
534
void
535
WifiRadioEnergyModelPhyListener::NotifySleep (void)
536
{
537
  NS_LOG_FUNCTION (this);
538
  if (m_changeStateCallback.IsNull ())
539
    {
540
      NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
541
    }
542
  m_changeStateCallback (WifiPhy::SLEEP);
543
  m_switchToIdleEvent.Cancel ();
544
}
545
546
void
547
WifiRadioEnergyModelPhyListener::NotifyWakeup(void)
548
{
549
  NS_LOG_FUNCTION (this);
550
  if (m_changeStateCallback.IsNull ())
551
    {
552
      NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
553
    }
554
  m_changeStateCallback (WifiPhy::IDLE);
555
}
556
557
/*
558
 * Private function state here.
559
 */
560
561
void
562
WifiRadioEnergyModelPhyListener::SwitchToIdle (void)
563
{
564
  NS_LOG_FUNCTION (this);
565
  if (m_changeStateCallback.IsNull ())
566
    {
567
      NS_FATAL_ERROR ("WifiRadioEnergyModelPhyListener:Change state callback not set!");
568
    }
569
  m_changeStateCallback (WifiPhy::IDLE);
570
}
571
572
} // namespace ns3
(-)a/src/wifi/model/wifi-radio-energy-model.h (+363 lines)
Line 0    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2010 Network Security Lab, University of Washington, Seattle.
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
 * Authors: Sidharth Nabar <snabar@uw.edu>, He Wu <mdzz@u.washington.edu>
19
 */
20
21
#ifndef WIFI_RADIO_ENERGY_MODEL_H
22
#define WIFI_RADIO_ENERGY_MODEL_H
23
24
#include "ns3/device-energy-model.h"
25
#include "ns3/nstime.h"
26
#include "ns3/event-id.h"
27
#include "ns3/traced-value.h"
28
#include "ns3/wifi-phy.h"
29
30
namespace ns3 {
31
32
class WifiTxCurrentModel;
33
34
/**
35
 * \ingroup energy
36
 * A WifiPhy listener class for notifying the WifiRadioEnergyModel of Wifi radio
37
 * state change.
38
 *
39
 */
40
class WifiRadioEnergyModelPhyListener : public WifiPhyListener
41
{
42
public:
43
  /**
44
   * Callback type for updating the transmit current based on the nominal tx power.
45
   */
46
  typedef Callback<void, double> UpdateTxCurrentCallback;
47
48
  WifiRadioEnergyModelPhyListener ();
49
  virtual ~WifiRadioEnergyModelPhyListener ();
50
51
  /**
52
   * \brief Sets the change state callback. Used by helper class.
53
   *
54
   * \param callback Change state callback.
55
   */
56
  void SetChangeStateCallback (DeviceEnergyModel::ChangeStateCallback callback);
57
58
  /**
59
   * \brief Sets the update tx current callback.
60
   *
61
   * \param callback Update tx current callback.
62
   */
63
  void SetUpdateTxCurrentCallback (UpdateTxCurrentCallback callback);
64
65
  /**
66
   * \brief Switches the WifiRadioEnergyModel to RX state.
67
   *
68
   * \param duration the expected duration of the packet reception.
69
   *
70
   * Defined in ns3::WifiPhyListener
71
   */
72
  virtual void NotifyRxStart (Time duration);
73
74
  /**
75
   * \brief Switches the WifiRadioEnergyModel back to IDLE state.
76
   *
77
   * Defined in ns3::WifiPhyListener
78
   *
79
   * Note that for the WifiRadioEnergyModel, the behavior of the function is the
80
   * same as NotifyRxEndError.
81
   */
82
  virtual void NotifyRxEndOk (void);
83
84
  /**
85
   * \brief Switches the WifiRadioEnergyModel back to IDLE state.
86
   *
87
   * Defined in ns3::WifiPhyListener
88
   *
89
   * Note that for the WifiRadioEnergyModel, the behavior of the function is the
90
   * same as NotifyRxEndOk.
91
   */
92
  virtual void NotifyRxEndError (void);
93
94
  /**
95
   * \brief Switches the WifiRadioEnergyModel to TX state and switches back to
96
   * IDLE after TX duration.
97
   *
98
   * \param duration the expected transmission duration.
99
   * \param txPowerDbm the nominal tx power in dBm
100
   *
101
   * Defined in ns3::WifiPhyListener
102
   */
103
  virtual void NotifyTxStart (Time duration, double txPowerDbm);
104
105
  /**
106
   * \param duration the expected busy duration.
107
   *
108
   * Defined in ns3::WifiPhyListener
109
   */
110
  virtual void NotifyMaybeCcaBusyStart (Time duration);
111
112
  /**
113
   * \param duration the expected channel switching duration.
114
   *
115
   * Defined in ns3::WifiPhyListener
116
   */
117
  virtual void NotifySwitchingStart (Time duration);
118
119
  /**
120
   * Defined in ns3::WifiPhyListener
121
   */
122
  virtual void NotifySleep (void);
123
124
  /**
125
   * Defined in ns3::WifiPhyListener
126
   */
127
  virtual void NotifyWakeup (void);
128
129
private:
130
  /**
131
   * A helper function that makes scheduling m_changeStateCallback possible.
132
   */
133
  void SwitchToIdle (void);
134
135
private:
136
  /**
137
   * Change state callback used to notify the WifiRadioEnergyModel of a state
138
   * change.
139
   */
140
  DeviceEnergyModel::ChangeStateCallback m_changeStateCallback;
141
142
  /**
143
   * Callback used to update the tx current stored in WifiRadioEnergyModel based on 
144
   * the nominal tx power used to transmit the current frame.
145
   */
146
  UpdateTxCurrentCallback m_updateTxCurrentCallback;
147
148
  EventId m_switchToIdleEvent;
149
};
150
151
// -------------------------------------------------------------------------- //
152
153
/**
154
 * \ingroup energy
155
 * \brief A WiFi radio energy model.
156
 * 
157
 * 4 states are defined for the radio: TX, RX, IDLE, SLEEP. Default state is
158
 * IDLE.
159
 * The different types of transactions that are defined are: 
160
 *  1. Tx: State goes from IDLE to TX, radio is in TX state for TX_duration,
161
 *     then state goes from TX to IDLE.
162
 *  2. Rx: State goes from IDLE to RX, radio is in RX state for RX_duration,
163
 *     then state goes from RX to IDLE.
164
 *  3. Go_to_Sleep: State goes from IDLE to SLEEP.
165
 *  4. End_of_Sleep: State goes from SLEEP to IDLE.
166
 * The class keeps track of what state the radio is currently in.
167
 *
168
 * Energy calculation: For each transaction, this model notifies EnergySource
169
 * object. The EnergySource object will query this model for the total current.
170
 * Then the EnergySource object uses the total current to calculate energy.
171
 *
172
 * Default values for power consumption are based on measurements reported in:
173
 * 
174
 * Daniel Halperin, Ben Greenstein, Anmol Sheth, David Wetherall,
175
 * "Demystifying 802.11n power consumption", Proceedings of HotPower'10 
176
 * 
177
 * Power consumption in Watts (single antenna):
178
 * 
179
 * \f$ P_{tx} = 1.14 \f$ (transmit at 0dBm)
180
 * 
181
 * \f$ P_{rx} = 0.94 \f$
182
 * 
183
 * \f$ P_{idle} = 0.82 \f$
184
 * 
185
 * \f$ P_{sleep} = 0.10 \f$
186
 * 
187
 * Hence, considering the default supply voltage of 3.0 V for the basic energy
188
 * source, the default current values in Ampere are:
189
 * 
190
 * \f$ I_{tx} = 0.380 \f$
191
 * 
192
 * \f$ I_{rx} = 0.313 \f$
193
 * 
194
 * \f$ I_{idle} = 0.273 \f$
195
 * 
196
 * \f$ I_{sleep} = 0.033 \f$
197
 * 
198
 * The dependence of the power consumption in transmission mode on the nominal
199
 * transmit power can also be achieved through a wifi tx current model.
200
 *
201
 */
202
class WifiRadioEnergyModel : public DeviceEnergyModel
203
{
204
public:
205
  /**
206
   * Callback type for energy depletion handling.
207
   */
208
  typedef Callback<void> WifiRadioEnergyDepletionCallback;
209
210
  /**
211
   * Callback type for energy recharged handling.
212
   */
213
  typedef Callback<void> WifiRadioEnergyRechargedCallback;
214
215
public:
216
  static TypeId GetTypeId (void);
217
  WifiRadioEnergyModel ();
218
  virtual ~WifiRadioEnergyModel ();
219
220
  /**
221
   * \brief Sets pointer to EnergySouce installed on node.
222
   *
223
   * \param source Pointer to EnergySource installed on node.
224
   *
225
   * Implements DeviceEnergyModel::SetEnergySource.
226
   */
227
  virtual void SetEnergySource (Ptr<EnergySource> source);
228
229
  /**
230
   * \returns Total energy consumption of the wifi device.
231
   *
232
   * Implements DeviceEnergyModel::GetTotalEnergyConsumption.
233
   */
234
  virtual double GetTotalEnergyConsumption (void) const;
235
236
  // Setter & getters for state power consumption.
237
  double GetIdleCurrentA (void) const;
238
  void SetIdleCurrentA (double idleCurrentA);
239
  double GetCcaBusyCurrentA (void) const;
240
  void SetCcaBusyCurrentA (double ccaBusyCurrentA);
241
  double GetTxCurrentA (void) const;
242
  void SetTxCurrentA (double txCurrentA);
243
  double GetRxCurrentA (void) const;
244
  void SetRxCurrentA (double rxCurrentA);
245
  double GetSwitchingCurrentA (void) const;
246
  void SetSwitchingCurrentA (double switchingCurrentA);
247
  double GetSleepCurrentA (void) const;
248
  void SetSleepCurrentA (double sleepCurrentA);
249
250
  /**
251
   * \returns Current state.
252
   */
253
  WifiPhy::State GetCurrentState (void) const;
254
255
  /**
256
   * \param callback Callback function.
257
   *
258
   * Sets callback for energy depletion handling.
259
   */
260
  void SetEnergyDepletionCallback (WifiRadioEnergyDepletionCallback callback);
261
262
  /**
263
   * \param callback Callback function.
264
   *
265
   * Sets callback for energy recharged handling.
266
   */
267
  void SetEnergyRechargedCallback (WifiRadioEnergyRechargedCallback callback);
268
269
  /**
270
   * \param model the model used to compute the wifi tx current.
271
   */
272
  void SetTxCurrentModel (Ptr<WifiTxCurrentModel> model);
273
274
  /**
275
   * \brief Calls the CalcTxCurrent method of the tx current model to
276
   *        compute the tx current based on such model
277
   * 
278
   * \param txPowerDbm the nominal tx power in dBm
279
   */
280
  void SetTxCurrentFromModel (double txPowerDbm);
281
282
  /**
283
   * \brief Changes state of the WifiRadioEnergyMode.
284
   *
285
   * \param newState New state the wifi radio is in.
286
   *
287
   * Implements DeviceEnergyModel::ChangeState.
288
   */
289
  virtual void ChangeState (int newState);
290
291
  /**
292
   * \brief Handles energy depletion.
293
   *
294
   * Implements DeviceEnergyModel::HandleEnergyDepletion
295
   */
296
  virtual void HandleEnergyDepletion (void);
297
298
  /**
299
   * \brief Handles energy recharged.
300
   *
301
   * Implements DeviceEnergyModel::HandleEnergyRecharged
302
   */
303
  virtual void HandleEnergyRecharged (void);
304
305
  /**
306
   * \returns Pointer to the PHY listener.
307
   */
308
  WifiRadioEnergyModelPhyListener * GetPhyListener (void);
309
310
311
private:
312
  void DoDispose (void);
313
314
  /**
315
   * \returns Current draw of device, at current state.
316
   *
317
   * Implements DeviceEnergyModel::GetCurrentA.
318
   */
319
  virtual double DoGetCurrentA (void) const;
320
321
  /**
322
   * \param state New state the radio device is currently in.
323
   *
324
   * Sets current state. This function is private so that only the energy model
325
   * can change its own state.
326
   */
327
  void SetWifiRadioState (const WifiPhy::State state);
328
329
private:
330
  Ptr<EnergySource> m_source;
331
332
  // Member variables for current draw in different radio modes.
333
  double m_txCurrentA;
334
  double m_rxCurrentA;
335
  double m_idleCurrentA;
336
  double m_ccaBusyCurrentA;
337
  double m_switchingCurrentA;
338
  double m_sleepCurrentA;
339
  Ptr<WifiTxCurrentModel> m_txCurrentModel;
340
341
  // This variable keeps track of the total energy consumed by this model.
342
  TracedValue<double> m_totalEnergyConsumption;
343
344
  // State variables.
345
  WifiPhy::State m_currentState;  // current state the radio is in
346
  Time m_lastUpdateTime;          // time stamp of previous energy update
347
348
  uint8_t m_nPendingChangeState;
349
  bool m_isSupersededChangeState;
350
351
  // Energy depletion callback
352
  WifiRadioEnergyDepletionCallback m_energyDepletionCallback;
353
354
  // Energy recharged callback
355
  WifiRadioEnergyRechargedCallback m_energyRechargedCallback;
356
357
  // WifiPhy listener
358
  WifiRadioEnergyModelPhyListener *m_listener;
359
};
360
361
} // namespace ns3
362
363
#endif /* WIFI_RADIO_ENERGY_MODEL_H */
(-)a/src/wifi/model/wifi-tx-current-model.cc (+143 lines)
Line 0    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2014 Universita' degli Studi di Napoli "Federico II"
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: Stefano Avallone <stefano.avallone@unina.it>
19
 */
20
21
#include "wifi-tx-current-model.h"
22
#include "ns3/log.h"
23
#include "ns3/boolean.h"
24
#include "ns3/double.h"
25
#include "ns3/string.h"
26
#include "ns3/pointer.h"
27
#include <cmath>
28
29
namespace ns3 {
30
31
NS_LOG_COMPONENT_DEFINE ("WifiTxCurrentModel");
32
33
// ------------------------------------------------------------------------- //
34
35
NS_OBJECT_ENSURE_REGISTERED (WifiTxCurrentModel);
36
37
TypeId 
38
WifiTxCurrentModel::GetTypeId (void)
39
{
40
  static TypeId tid = TypeId ("ns3::WifiTxCurrentModel")
41
    .SetParent<Object> ()
42
    .SetGroupName ("Energy")
43
  ;
44
  return tid;
45
}
46
47
WifiTxCurrentModel::WifiTxCurrentModel()
48
{
49
}
50
51
WifiTxCurrentModel::~WifiTxCurrentModel()
52
{
53
}
54
55
double
56
WifiTxCurrentModel::DbmToW (double dbm)
57
{
58
  double mW = std::pow (10.0, dbm / 10.0);
59
  return mW / 1000.0;
60
}
61
62
// ------------------------------------------------------------------------- //
63
64
NS_OBJECT_ENSURE_REGISTERED (LinearWifiTxCurrentModel);
65
66
TypeId 
67
LinearWifiTxCurrentModel::GetTypeId (void)
68
{
69
  static TypeId tid = TypeId ("ns3::LinearWifiTxCurrentModel")
70
    .SetParent<WifiTxCurrentModel> ()
71
    .AddConstructor<LinearWifiTxCurrentModel> ()
72
    .AddAttribute ("Eta", "The efficiency of the power amplifier.",
73
                   DoubleValue (0.10),
74
                   MakeDoubleAccessor (&LinearWifiTxCurrentModel::SetEta,
75
                                       &LinearWifiTxCurrentModel::GetEta),
76
                   MakeDoubleChecker<double> ())
77
    .AddAttribute ("Voltage", "The supply voltage (in Volts).",
78
                   DoubleValue (3.0),
79
                   MakeDoubleAccessor (&LinearWifiTxCurrentModel::SetVoltage,
80
                                       &LinearWifiTxCurrentModel::GetVoltage),
81
                   MakeDoubleChecker<double> ())
82
    .AddAttribute ("IdleCurrent", "The current in the IDLE state (in Watts).",
83
                   DoubleValue (0.273333),
84
                   MakeDoubleAccessor (&LinearWifiTxCurrentModel::SetIdleCurrent,
85
                                       &LinearWifiTxCurrentModel::GetIdleCurrent),
86
                   MakeDoubleChecker<double> ())
87
  ;
88
  return tid;
89
}
90
91
LinearWifiTxCurrentModel::LinearWifiTxCurrentModel ()
92
{
93
}
94
95
LinearWifiTxCurrentModel::~LinearWifiTxCurrentModel()
96
{
97
}
98
99
void
100
LinearWifiTxCurrentModel::SetEta (double eta)
101
{
102
  m_eta = eta;
103
}
104
105
void
106
LinearWifiTxCurrentModel::SetVoltage (double voltage)
107
{
108
  m_voltage = voltage;
109
}
110
111
void
112
LinearWifiTxCurrentModel::SetIdleCurrent (double idleCurrent)
113
{
114
  m_idleCurrent = idleCurrent;
115
}
116
117
double
118
LinearWifiTxCurrentModel::GetEta (void) const
119
{
120
  return m_eta;
121
}
122
123
double
124
LinearWifiTxCurrentModel::GetVoltage (void) const
125
{
126
  return m_voltage;
127
}
128
129
double
130
LinearWifiTxCurrentModel::GetIdleCurrent (void) const
131
{
132
  return m_idleCurrent;
133
}
134
135
double
136
LinearWifiTxCurrentModel::CalcTxCurrent (double txPowerDbm) const
137
{
138
  return DbmToW (txPowerDbm) / (m_voltage * m_eta) + m_idleCurrent;
139
}
140
141
// ------------------------------------------------------------------------- //
142
143
} // namespace ns3
(-)a/src/wifi/model/wifi-tx-current-model.h (+142 lines)
Line 0    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
 * Copyright (c) 2014 Universita' degli Studi di Napoli "Federico II"
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: Stefano Avallone <stefano.avallone@unina.it>
19
 */
20
21
#ifndef WIFI_TX_CURRENT_MODEL_H
22
#define WIFI_TX_CURRENT_MODEL_H
23
24
#include "ns3/object.h"
25
26
namespace ns3 {
27
28
/**
29
 * \ingroup energy
30
 * 
31
 * \brief Modelize the transmit current as a function of the transmit power and mode
32
 *
33
 */
34
class WifiTxCurrentModel : public Object
35
{
36
public:
37
  static TypeId GetTypeId (void);
38
39
  WifiTxCurrentModel ();
40
  virtual ~WifiTxCurrentModel ();
41
42
  /**
43
   * \param txPowerDbm the nominal tx power in dBm
44
   * \returns the transmit current (in Ampere)
45
   */
46
  virtual double CalcTxCurrent (double txPowerDbm) const = 0;
47
48
  /**
49
   * Convert from dBm to Watts.
50
   *
51
   * \param dbm the power in dBm
52
   * \return the equivalent Watts for the given dBm
53
   */
54
  static double DbmToW (double dbm);
55
};
56
57
/**
58
 * \ingroup energy
59
 *
60
 * \brief a linear model of the Wifi transmit current
61
 *
62
 * This model assumes that the transmit current is a linear function
63
 * of the nominal transmit power used to send the frame.
64
 * In particular, the power absorbed during the transmission of a frame \f$ W_{tx} \f$
65
 * is given by the power absorbed by the power amplifier \f$ W_{pa} \f$ plus the power
66
 * absorbed by the RF subsystem. The latter is assumed to be the same as the power
67
 * absorbed in the IDLE state \f$ W_{idle} \f$.
68
 * 
69
 * The efficiency \f$ \eta \f$ of the power amplifier is given by 
70
 * \f$ \eta = \frac{P_{tx}}{W_{pa}} \f$, where \f$ P_{tx} \f$ is the output power, i.e.,
71
 * the nominal transmit power. Hence, \f$ W_{pa} = \frac{P_{tx}}{\eta} \f$
72
 * 
73
 * It turns out that \f$ W_{tx} = \frac{P_{tx}}{\eta} + W_{idle} \f$. By dividing both
74
 * sides by the supply voltage \f$ V \f$: \f$ I_{tx} = \frac{P_{tx}}{V \cdot \eta} + I_{idle} \f$,
75
 * where \f$ I_{tx} \f$ and \f$ I_{idle} \f$ are, respectively, the transmit current and
76
 * the idle current.
77
 * 
78
 * For more information, refer to:
79
 * Francesco Ivan Di Piazza, Stefano Mangione, and Ilenia Tinnirello.
80
 * "On the Effects of Transmit Power Control on the Energy Consumption of WiFi Network Cards",
81
 * Proceedings of ICST QShine 2009, pp. 463--475
82
 * 
83
 * If the tx current corresponding to a given nominal transmit power is known, the efficiency
84
 * of the power amplifier is given by the above formula:
85
 * \f$ \eta = \frac{P_{tx}}{(I_{tx}-I_{idle})\cdot V} \f$
86
 * 
87
 */
88
class LinearWifiTxCurrentModel : public WifiTxCurrentModel
89
{
90
public:
91
  static TypeId GetTypeId (void);
92
93
  LinearWifiTxCurrentModel ();
94
  virtual ~LinearWifiTxCurrentModel ();
95
  
96
  /**
97
   * \param eta (dimension-less)
98
   *
99
   * Set the power amplifier efficiency.
100
   */
101
  void SetEta (double eta);
102
103
  /**
104
   * \param voltage (Volts)
105
   *
106
   * Set the supply voltage.
107
   */
108
  void SetVoltage (double voltage);
109
110
  /**
111
   * \param idleCurrent (Ampere)
112
   *
113
   * Set the current in the IDLE state.
114
   */
115
  void SetIdleCurrent (double idleCurrent);
116
117
  /**
118
   * \return the power amplifier efficiency.
119
   */
120
  double GetEta (void) const;
121
122
  /**
123
   * \return the supply voltage.
124
   */
125
  double GetVoltage (void) const;
126
127
  /**
128
   * \return the current in the IDLE state.
129
   */
130
  double GetIdleCurrent (void) const;
131
132
  double CalcTxCurrent (double txPowerDbm) const;
133
134
private:
135
  double m_eta;
136
  double m_voltage;
137
  double m_idleCurrent;
138
};
139
140
} // namespace ns3
141
142
#endif /* WIFI_TX_CURRENT_MODEL_H */
(-)a/src/wifi/wscript (-1 / +7 lines)
 Lines 1-7    Link Here 
1
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
1
## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
2
2
3
def build(bld):
3
def build(bld):
4
    obj = bld.create_ns3_module('wifi', ['network', 'propagation'])
4
    obj = bld.create_ns3_module('wifi', ['network', 'propagation', 'energy'])
5
    obj.source = [
5
    obj.source = [
6
        'model/wifi-information-element.cc',
6
        'model/wifi-information-element.cc',
7
        'model/wifi-information-element-vector.cc',
7
        'model/wifi-information-element-vector.cc',
 Lines 69-74    Link Here 
69
        'model/mpdu-aggregator.cc',
69
        'model/mpdu-aggregator.cc',
70
        'model/mpdu-standard-aggregator.cc',
70
        'model/mpdu-standard-aggregator.cc',
71
        'model/ampdu-tag.cc',
71
        'model/ampdu-tag.cc',
72
        'model/wifi-radio-energy-model.cc',
73
        'model/wifi-tx-current-model.cc',
74
        'helper/wifi-radio-energy-model-helper.cc',
72
        'helper/ht-wifi-mac-helper.cc',
75
        'helper/ht-wifi-mac-helper.cc',
73
        'helper/athstats-helper.cc',
76
        'helper/athstats-helper.cc',
74
        'helper/wifi-helper.cc',
77
        'helper/wifi-helper.cc',
 Lines 154-159    Link Here 
154
        'model/mpdu-aggregator.h',
157
        'model/mpdu-aggregator.h',
155
        'model/mpdu-standard-aggregator.h',
158
        'model/mpdu-standard-aggregator.h',
156
        'model/ampdu-tag.h',
159
        'model/ampdu-tag.h',
160
        'model/wifi-radio-energy-model.h',
161
        'model/wifi-tx-current-model.h',
162
        'helper/wifi-radio-energy-model-helper.h',
157
        'helper/ht-wifi-mac-helper.h',
163
        'helper/ht-wifi-mac-helper.h',
158
        'helper/athstats-helper.h',
164
        'helper/athstats-helper.h',
159
        'helper/wifi-helper.h',
165
        'helper/wifi-helper.h',

Return to bug 1941