A Discrete-Event Network Simulator
API
rv-battery-model-test.cc
Go to the documentation of this file.
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/rv-battery-model.h"
22 #include "ns3/wifi-radio-energy-model.h"
23 #include "ns3/rv-battery-model-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/command-line.h"
33 #include "ns3/string.h"
34 #include "ns3/yans-wifi-helper.h"
35 #include <cmath>
36 
37 using namespace ns3;
38 
39 NS_LOG_COMPONENT_DEFINE ("RvBatteryModelTestSuite");
40 
55 {
56 public:
58  virtual ~BatteryLifetimeTest ();
59 
66  void CreateLoadProfiles (void);
67 
76  bool ConstantLoadTest (double load, Time expLifetime);
77 
87  bool VariableLoadTest (std::vector<double> loads,
88  std::vector<Time> timeStamps,
89  Time expLifetime);
90 
92  typedef struct LoadProfile
93  {
94  std::vector<double> loads;
95  std::vector<Time> timeStamps;
98  } LoadProfile;
99 
100  std::vector<LoadProfile> m_loadProfiles;
101  double m_alpha;
102  double m_beta;
103 };
104 
106 {
107  // Itsy battery
108  m_alpha = 35220;
109  m_beta = 0.637;
110 }
111 
113 {
114 }
115 
116 void
118 {
119  // create set of load profiles
120  LoadProfile profile;
121 
122  std::vector<double> loads;
123  std::vector<Time> timeStamps;
124 
125  // C1
126  loads.push_back (0.628);
127  loads.push_back (0);
128  loads.push_back (0.628);
129 
130  timeStamps.push_back (Seconds (0));
131  timeStamps.push_back (Seconds (19.5 * 60));
132  timeStamps.push_back (Seconds (26.0 * 60));
133 
134  profile.loads = loads;
135  profile.timeStamps = timeStamps;
136  profile.itsyLifetime = Seconds (55.0 * 60); // 55.0 minutes
137  profile.dualFoilLifeTime = Seconds (36.2 * 60); // 36.2 minutes
138 
139  m_loadProfiles.push_back (profile);
140 
141  loads.clear ();
142  timeStamps.clear ();
143 
144  // C2
145  loads.push_back (0.4947);
146  loads.push_back (0);
147  loads.push_back (0.4947);
148 
149  timeStamps.push_back (Seconds (0));
150  timeStamps.push_back (Seconds (31.0 * 60));
151  timeStamps.push_back (Seconds (41.3 * 60));
152 
153  profile.loads = loads;
154  profile.timeStamps = timeStamps;
155  profile.itsyLifetime = Seconds (73.9 * 60); // 73.9 minutes
156  profile.dualFoilLifeTime = Seconds (55.8 * 60); // 55.8 minutes
157 
158  m_loadProfiles.push_back (profile);
159 
160  loads.clear ();
161  timeStamps.clear ();
162 
163  // C3
164  loads.push_back (0.4256);
165  loads.push_back (0);
166  loads.push_back (0.4256);
167 
168  timeStamps.push_back (Seconds (0));
169  timeStamps.push_back (Seconds (41.0 * 60));
170  timeStamps.push_back (Seconds (54.6 * 60));
171 
172  profile.loads = loads;
173  profile.timeStamps = timeStamps;
174  profile.itsyLifetime = Seconds (88.8 * 60); // 88.8 minutes
175  profile.dualFoilLifeTime = Seconds (71.8 * 60); // 71.8 minutes
176 
177  m_loadProfiles.push_back (profile);
178 
179  loads.clear ();
180  timeStamps.clear ();
181 
182  // C4
183  loads.push_back (0.2923);
184  loads.push_back (0);
185  loads.push_back (0.2923);
186 
187  timeStamps.push_back (Seconds (0));
188  timeStamps.push_back (Seconds (74.6 * 60));
189  timeStamps.push_back (Seconds (99.5 * 60));
190 
191  profile.loads = loads;
192  profile.timeStamps = timeStamps;
193  profile.itsyLifetime = Seconds (137.8 * 60); // 137.8 minutes
194  profile.dualFoilLifeTime = Seconds (124.9 * 60); // 124.9 minutes
195 
196  m_loadProfiles.push_back (profile);
197 
198  loads.clear ();
199  timeStamps.clear ();
200 
201  // C5
202  loads.push_back (0.2227);
203  loads.push_back (0);
204  loads.push_back (0.2227);
205 
206  timeStamps.push_back (Seconds (0));
207  timeStamps.push_back (Seconds (105.7 * 60));
208  timeStamps.push_back (Seconds (140.9 * 60));
209 
210  profile.loads = loads;
211  profile.timeStamps = timeStamps;
212  profile.itsyLifetime = Seconds (185.8 * 60); // 185.8 minutes
213  profile.dualFoilLifeTime = Seconds (176.7 * 60); // 176.7 minutes
214 
215  m_loadProfiles.push_back (profile);
216 
217  loads.clear ();
218  timeStamps.clear ();
219 
220  // C6
221  loads.push_back (0.628);
222  loads.push_back (0);
223  loads.push_back (0.628);
224 
225  timeStamps.push_back (Seconds (0));
226  timeStamps.push_back (Seconds (19.5 * 60));
227  timeStamps.push_back (Seconds (29.9 * 60));
228 
229  profile.loads = loads;
230  profile.timeStamps = timeStamps;
231  profile.itsyLifetime = Seconds (58.9 * 60); // 58.9 minutes
232  profile.dualFoilLifeTime = Seconds (41.0 * 60); // 41.0 minutes
233 
234  m_loadProfiles.push_back (profile);
235 
236  loads.clear ();
237  timeStamps.clear ();
238 
239  // C7
240  loads.push_back (0.628);
241  loads.push_back (0);
242  loads.push_back (0.628);
243 
244  timeStamps.push_back (Seconds (0));
245  timeStamps.push_back (Seconds (19.5 * 60));
246  timeStamps.push_back (Seconds (22.1 * 60));
247 
248  profile.loads = loads;
249  profile.timeStamps = timeStamps;
250  profile.itsyLifetime = Seconds (51.1 * 60); // 51.1 minutes
251  profile.dualFoilLifeTime = Seconds (30.8 * 60); // 30.8 minutes
252 
253  m_loadProfiles.push_back (profile);
254 
255  loads.clear ();
256  timeStamps.clear ();
257 
258  // C8
259  loads.push_back (0.628);
260  loads.push_back (0);
261  loads.push_back (0.628);
262 
263  timeStamps.push_back (Seconds (0));
264  timeStamps.push_back (Seconds (23.4 * 60));
265  timeStamps.push_back (Seconds (29.9 * 60));
266 
267  profile.loads = loads;
268  profile.timeStamps = timeStamps;
269  profile.itsyLifetime = Seconds (55.0 * 60); // 55.0 minutes
270  profile.dualFoilLifeTime = Seconds (37.4 * 60); // 37.4 minutes
271 
272  m_loadProfiles.push_back (profile);
273 
274  loads.clear ();
275  timeStamps.clear ();
276 
277  // C9
278  loads.push_back (0.628);
279  loads.push_back (0);
280  loads.push_back (0.628);
281 
282  timeStamps.push_back (Seconds (0));
283  timeStamps.push_back (Seconds (15.6 * 60));
284  timeStamps.push_back (Seconds (22.1 * 60));
285 
286  profile.loads = loads;
287  profile.timeStamps = timeStamps;
288  profile.itsyLifetime = Seconds (55.0 * 60); // 55.0 minutes
289  profile.dualFoilLifeTime = Seconds (35.2 * 60); // 35.2 minutes
290 
291  m_loadProfiles.push_back (profile);
292 
293  loads.clear ();
294  timeStamps.clear ();
295 
296  // C10
297  loads.push_back (0.300);
298  loads.push_back (0.628);
299  loads.push_back (0.4947);
300  loads.push_back (0.2523);
301  loads.push_back (0.2341);
302  loads.push_back (0.1379);
303  loads.push_back (0.1139);
304  loads.push_back (0.2656);
305 
306  timeStamps.push_back (Seconds (0));
307  timeStamps.push_back (Seconds (0.5 * 60));
308  timeStamps.push_back (Seconds (5.5 * 60));
309  timeStamps.push_back (Seconds (10.5 * 60));
310  timeStamps.push_back (Seconds (35.5 * 60));
311  timeStamps.push_back (Seconds (60.5 * 60));
312  timeStamps.push_back (Seconds (85.5 * 60));
313  timeStamps.push_back (Seconds (110.5 * 60));
314 
315  profile.loads = loads;
316  profile.timeStamps = timeStamps;
317  profile.itsyLifetime = Seconds (144.3 * 60); // 144.3 minutes
318  profile.dualFoilLifeTime = Seconds (132.6 * 60); // 132.6 minutes
319 
320  m_loadProfiles.push_back (profile);
321 
322  loads.clear ();
323  timeStamps.clear ();
324 
325  // C11
326  loads.push_back (0.300);
327  loads.push_back (0.1139);
328  loads.push_back (0.1379);
329  loads.push_back (0.2341);
330  loads.push_back (0.2523);
331  loads.push_back (0.4947);
332  loads.push_back (0.628);
333  loads.push_back (0.2656);
334 
335  timeStamps.push_back (Seconds (0));
336  timeStamps.push_back (Seconds (0.5 * 60));
337  timeStamps.push_back (Seconds (25.5 * 60));
338  timeStamps.push_back (Seconds (50.5 * 60));
339  timeStamps.push_back (Seconds (75.5 * 60));
340  timeStamps.push_back (Seconds (100.5 * 60));
341  timeStamps.push_back (Seconds (105.5 * 60));
342  timeStamps.push_back (Seconds (110.5 * 60));
343 
344  profile.loads = loads;
345  profile.timeStamps = timeStamps;
346  profile.itsyLifetime = Seconds (144.3 * 60); // 144.3 minutes
347  profile.dualFoilLifeTime = Seconds (107.4 * 60); // 107.4 minutes
348 
349  m_loadProfiles.push_back (profile);
350 
351  loads.clear ();
352  timeStamps.clear ();
353 
354  // C12
355  loads.push_back (0.300);
356  loads.push_back (0.1139);
357  loads.push_back (0.1379);
358  loads.push_back (0.2341);
359  loads.push_back (0.2523);
360  loads.push_back (0.4947);
361  loads.push_back (0.0);
362  loads.push_back (0.300);
363  loads.push_back (0.628);
364  loads.push_back (0.2656);
365 
366  timeStamps.push_back (Seconds (0));
367  timeStamps.push_back (Seconds (0.5 * 60));
368  timeStamps.push_back (Seconds (25.5 * 60));
369  timeStamps.push_back (Seconds (50.5 * 60));
370  timeStamps.push_back (Seconds (75.5 * 60));
371  timeStamps.push_back (Seconds (100.5 * 60));
372  timeStamps.push_back (Seconds (105.5 * 60));
373  timeStamps.push_back (Seconds (130.5 * 60));
374  timeStamps.push_back (Seconds (131.0 * 60));
375  timeStamps.push_back (Seconds (136.0 * 60));
376 
377  profile.loads = loads;
378  profile.timeStamps = timeStamps;
379  profile.itsyLifetime = Seconds (169.3 * 60); // 169.3 minutes
380  profile.dualFoilLifeTime = Seconds (155.4 * 60); // 155.4 minutes
381 
382  m_loadProfiles.push_back (profile);
383 
384  loads.clear ();
385  timeStamps.clear ();
386 
387  // C13
388  loads.push_back (0.300);
389  timeStamps.push_back (Seconds (0));
390 
391  for (int i = 0; i < 5; i++)
392  {
393  loads.push_back (0.628);
394  loads.push_back (0.4947);
395  loads.push_back (0.2523);
396  loads.push_back (0.2341);
397  loads.push_back (0.1379);
398  loads.push_back (0.1139);
399 
400  timeStamps.push_back (Seconds ((0.5 + i * 22.5) * 60));
401  timeStamps.push_back (Seconds ((1.5 + i * 22.5) * 60));
402  timeStamps.push_back (Seconds ((2.5 + i * 22.5) * 60));
403  timeStamps.push_back (Seconds ((7.5 + i * 22.5) * 60));
404  timeStamps.push_back (Seconds ((12.5 + i * 22.5) * 60));
405  timeStamps.push_back (Seconds ((17.5 + i * 22.5) * 60));
406  }
407 
408  loads.push_back (0.2656);
409  timeStamps.push_back (Seconds (110.5 * 60));
410 
411  profile.loads = loads;
412  profile.timeStamps = timeStamps;
413  profile.itsyLifetime = Seconds (144.3 * 60); // 144.3 minutes
414  profile.dualFoilLifeTime = Seconds (131.7 * 60); // 131.7 minutes
415 
416  m_loadProfiles.push_back (profile);
417 
418  loads.clear ();
419  timeStamps.clear ();
420 
421  // C14, time stamp calculation in paper is off, using our own estimated value
422  loads.push_back (0.300);
423  timeStamps.push_back (Seconds (0));
424 
425  for (int i = 0; i < 5; i++)
426  {
427  loads.push_back (0.1139);
428  loads.push_back (0.1379);
429  loads.push_back (0.2341);
430  loads.push_back (0.2523);
431  loads.push_back (0.4947);
432  loads.push_back (0.628);
433 
434  timeStamps.push_back (Seconds ((0.5 + i * 22.5) * 60));
435  timeStamps.push_back (Seconds ((5.5 + i * 22.5) * 60));
436  timeStamps.push_back (Seconds ((10.5 + i * 22.5) * 60));
437  timeStamps.push_back (Seconds ((15.5 + i * 22.5) * 60));
438  timeStamps.push_back (Seconds ((20.5 + i * 22.5) * 60));
439  timeStamps.push_back (Seconds ((21.5 + i * 22.5) * 60));
440  }
441 
442  loads.push_back (0.2656);
443  timeStamps.push_back (Seconds (112.5 * 60));
444 
445  profile.loads = loads;
446  profile.timeStamps = timeStamps;
447  profile.itsyLifetime = Seconds (141.5 * 60); // 141.5 minutes
448  profile.dualFoilLifeTime = Seconds (126.3 * 60); // 126.3 minutes
449 
450  m_loadProfiles.push_back (profile);
451 
452  loads.clear ();
453  timeStamps.clear ();
454 
455  // C15
456  loads.push_back (0.2227);
457  loads.push_back (0.2045);
458  loads.push_back (0.1083);
459  loads.push_back (0.0843);
460  loads.push_back (0.2227);
461 
462  timeStamps.push_back (Seconds (0));
463  timeStamps.push_back (Seconds (50.0 * 60));
464  timeStamps.push_back (Seconds (100.0 * 60));
465  timeStamps.push_back (Seconds (150.0 * 60));
466  timeStamps.push_back (Seconds (200.0 * 60));
467 
468  profile.loads = loads;
469  profile.timeStamps = timeStamps;
470  profile.itsyLifetime = Seconds (211.4 * 60); // 211.4 minutes
471  profile.dualFoilLifeTime = Seconds (209.2 * 60); // 209.2 minutes
472 
473  m_loadProfiles.push_back (profile);
474 
475  loads.clear ();
476  timeStamps.clear ();
477 
478  // C16
479  loads.push_back (0.0843);
480  loads.push_back (0.1083);
481  loads.push_back (0.2045);
482  loads.push_back (0.2227);
483  loads.push_back (0.2227);
484 
485  timeStamps.push_back (Seconds (0));
486  timeStamps.push_back (Seconds (50.0 * 60));
487  timeStamps.push_back (Seconds (100.0 * 60));
488  timeStamps.push_back (Seconds (150.0 * 60));
489  timeStamps.push_back (Seconds (200.0 * 60));
490 
491  profile.loads = loads;
492  profile.timeStamps = timeStamps;
493  profile.itsyLifetime = Seconds (211.4 * 60); // 211.4 minutes
494  profile.dualFoilLifeTime = Seconds (200.7 * 60); // 200.7 minutes
495 
496  m_loadProfiles.push_back (profile);
497 
498  loads.clear ();
499  timeStamps.clear ();
500 
501  // C17
502  loads.push_back (0.0843);
503  loads.push_back (0.1083);
504  loads.push_back (0.2045);
505  loads.push_back (0.0);
506  loads.push_back (0.2227);
507  loads.push_back (0.2227);
508 
509  timeStamps.push_back (Seconds (0));
510  timeStamps.push_back (Seconds (50.0 * 60));
511  timeStamps.push_back (Seconds (100.0 * 60));
512  timeStamps.push_back (Seconds (150.0 * 60));
513  timeStamps.push_back (Seconds (200.0 * 60));
514  timeStamps.push_back (Seconds (250.0 * 60));
515 
516  profile.loads = loads;
517  profile.timeStamps = timeStamps;
518  profile.itsyLifetime = Seconds (261.4 * 60); // 261.4 minutes
519  profile.dualFoilLifeTime = Seconds (251.2 * 60); // 251.2 minutes
520 
521  m_loadProfiles.push_back (profile);
522 
523  loads.clear ();
524  timeStamps.clear ();
525 
526  // C18
527  for (int i = 0; i < 10; i++)
528  {
529  loads.push_back (0.0843);
530  loads.push_back (0.1083);
531  loads.push_back (0.2045);
532  loads.push_back (0.2227);
533 
534  timeStamps.push_back (Seconds ((0.0 + i * 20.0) * 60));
535  timeStamps.push_back (Seconds ((5.0 + i * 20.0) * 60));
536  timeStamps.push_back (Seconds ((10.0 + i * 20.0) * 60));
537  timeStamps.push_back (Seconds ((15.0 + i * 20.0) * 60));
538  }
539 
540  loads.push_back (0.2227);
541  timeStamps.push_back (Seconds (200.0));
542 
543  profile.loads = loads;
544  profile.timeStamps = timeStamps;
545  profile.itsyLifetime = Seconds (211.4 * 60); // 211.4 minutes
546  profile.dualFoilLifeTime = Seconds (204.6 * 60); // 204.6 minutes
547 
548  m_loadProfiles.push_back (profile);
549 
550  loads.clear ();
551  timeStamps.clear ();
552 
553  // C19
554  for (int i = 0; i < 10; i++)
555  {
556  loads.push_back (0.0755);
557  loads.push_back (0.0949);
558  loads.push_back (0.2045);
559  loads.push_back (0.2227);
560 
561  timeStamps.push_back (Seconds ((0.0 + i * 20.0) * 60));
562  timeStamps.push_back (Seconds ((5.0 + i * 20.0) * 60));
563  timeStamps.push_back (Seconds ((10.0 + i * 20.0) * 60));
564  timeStamps.push_back (Seconds ((15.0 + i * 20.0) * 60));
565  }
566 
567  loads.push_back (0.2227);
568  timeStamps.push_back (Seconds (200.0));
569 
570  profile.loads = loads;
571  profile.timeStamps = timeStamps;
572  profile.itsyLifetime = Seconds (216.4 * 60); // 216.4 minutes
573  profile.dualFoilLifeTime = Seconds (208.7 * 60); // 208.7 minutes
574 
575  m_loadProfiles.push_back (profile);
576 
577  loads.clear ();
578  timeStamps.clear ();
579 
580  // C20
581  for (int i = 0; i < 50; i++)
582  {
583  loads.push_back (0.4947);
584  loads.push_back (0.628);
585 
586  timeStamps.push_back (Seconds ((0.0 + i * 2.0) * 60));
587  timeStamps.push_back (Seconds ((1.0 + i * 2.0) * 60));
588  }
589 
590  profile.loads = loads;
591  profile.timeStamps = timeStamps;
592  profile.itsyLifetime = Seconds (55.3 * 60); // 55.3 minutes
593  profile.dualFoilLifeTime = Seconds (33.2 * 60); // 33.2 minutes
594 
595  m_loadProfiles.push_back (profile);
596 
597  loads.clear ();
598  timeStamps.clear ();
599 
600  // C21
601  for (int i = 0; i < 50; i++)
602  {
603  loads.push_back (0.4947);
604  loads.push_back (0.628);
605  loads.push_back (0.0576);
606 
607  timeStamps.push_back (Seconds ((0.0 + i * 3.0) * 60));
608  timeStamps.push_back (Seconds ((1.0 + i * 3.0) * 60));
609  timeStamps.push_back (Seconds ((2.0 + i * 3.0) * 60));
610  }
611 
612  profile.loads = loads;
613  profile.timeStamps = timeStamps;
614  profile.itsyLifetime = Seconds (79.6 * 60); // 79.6 minutes
615  profile.dualFoilLifeTime = Seconds (55.9 * 60); // 55.9 minutes
616 
617  m_loadProfiles.push_back (profile);
618 
619  loads.clear ();
620  timeStamps.clear ();
621 
622  // C22
623  for (int i = 0; i < 150; i++)
624  {
625  loads.push_back (0.005 + 0.005 * i);
626  timeStamps.push_back (Seconds ((0.0 + i * 1.0) * 60));
627  }
628 
629  profile.loads = loads;
630  profile.timeStamps = timeStamps;
631  profile.itsyLifetime = Seconds (112.2 * 60); // 112.2 minutes
632  profile.dualFoilLifeTime = Seconds (94.5 * 60); // 94.5 minutes
633 
634  m_loadProfiles.push_back (profile);
635 
636  loads.clear ();
637  timeStamps.clear ();
638 }
639 
640 int
641 main (int argc, char **argv)
642 {
643  CommandLine cmd (__FILE__);
644  cmd.Parse (argc, argv);
645 
646  NS_LOG_DEBUG ("Constant load run.");
647 
648  BatteryLifetimeTest test;
649  int ret = 0;
650 
651  if (test.ConstantLoadTest (0.640, Seconds (2844.0)))
652  {
653  ret = 1;
654  std::cerr << "Problems with constant load test (640mA)." << std::endl;
655  }
656  if (test.ConstantLoadTest (0.320, Seconds (6146.0)))
657  {
658  ret = 1;
659  std::cerr << "Problems with constant load test (320mA)." << std::endl;
660  }
661  if (test.ConstantLoadTest (0.128, Seconds (16052.0)))
662  {
663  ret = 1;
664  std::cerr << "Problems with constant load test (128mA)." << std::endl;
665  }
666  if (test.ConstantLoadTest (0.064, Seconds (32561.0)))
667  {
668  ret = 1;
669  std::cerr << "Problems with constant load test (64mA)." << std::endl;
670  }
671  if (test.ConstantLoadTest (0.032, Seconds (65580.0)))
672  {
673  ret = 1;
674  std::cerr << "Problems with constant load test (32mA)." << std::endl;
675  }
676 
677  // create load profiles for variable load test
678  test.CreateLoadProfiles ();
679 
680  // variable load with Itsy battery
681  NS_LOG_DEBUG ("\n\nItsy");
682  test.m_alpha = 35220;
683  test.m_beta = 0.637;
684  for (uint32_t i = 0; i < test.m_loadProfiles.size (); i++)
685  {
686  NS_LOG_DEBUG ("========");
687  NS_LOG_DEBUG ("Variable load profile C" << i + 1);
688  if (test.VariableLoadTest (test.m_loadProfiles[i].loads,
689  test.m_loadProfiles[i].timeStamps,
690  test.m_loadProfiles[i].itsyLifetime))
691  {
692  ret = 1;
693  std::cerr << "Problems with variable load test (Itsy)." << std::endl;
694  }
695  }
696 
697  // variable load with DUALFOIL battery
698  NS_LOG_DEBUG ("\n\nDUALFOIL");
699  test.m_alpha = 40027;
700  test.m_beta = 0.276;
701  for (uint32_t i = 0; i < test.m_loadProfiles.size (); i++)
702  {
703  NS_LOG_DEBUG ("========");
704  NS_LOG_DEBUG ("Variable load profile C" << i + 1);
705  if (test.VariableLoadTest (test.m_loadProfiles[i].loads,
706  test.m_loadProfiles[i].timeStamps,
707  test.m_loadProfiles[i].dualFoilLifeTime))
708  {
709  ret = 1;
710  std::cerr << "Problems with variable load test (DUALFOIL)." << std::endl;
711  }
712  }
713 
714  return ret;
715 }
716 
717 bool
718 BatteryLifetimeTest::ConstantLoadTest (double load, Time expLifetime)
719 {
720  // create single node
721  NodeContainer c;
722  c.Create (1);
723 
724  std::string phyMode ("DsssRate1Mbps");
725 
726  // disable fragmentation for frames below 2200 bytes
727  Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold",
728  StringValue ("2200"));
729  // turn off RTS/CTS for frames below 2200 bytes
730  Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold",
731  StringValue ("2200"));
732  // Fix non-unicast data rate to be the same as that of unicast
733  Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode",
734  StringValue (phyMode));
735 
736  // install YansWifiPhy
738  wifi.SetStandard (WIFI_STANDARD_80211b);
739 
740  YansWifiPhyHelper wifiPhy;
741  /*
742  * This is one parameter that matters when using FixedRssLossModel, set it to
743  * zero; otherwise, gain will be added.
744  */
745  wifiPhy.Set ("RxGain", DoubleValue (0));
746  // ns-3 supports RadioTap and Prism tracing extensions for 802.11b
748 
749  YansWifiChannelHelper wifiChannel;
750  wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
751  wifiPhy.SetChannel (wifiChannel.Create ());
752 
753  // Add a MAC and disable rate control
754  WifiMacHelper wifiMac;
755  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
756  "DataMode", StringValue (phyMode),
757  "ControlMode", StringValue (phyMode));
758  // Set it to ad-hoc mode
759  wifiMac.SetType ("ns3::AdhocWifiMac");
760  NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, c);
761 
762  // Create and install battery model and device models
763  // RV battery model
764  RvBatteryModelHelper rvModelHelper;
765  // Set alpha & beta values
766  rvModelHelper.Set ("RvBatteryModelAlphaValue", DoubleValue (m_alpha));
767  rvModelHelper.Set ("RvBatteryModelBetaValue", DoubleValue (m_beta));
768  rvModelHelper.Set ("RvBatteryModelLowBatteryThreshold", DoubleValue (0.0));
769  // install source
770  EnergySourceContainer sources = rvModelHelper.Install (c);
771  // device energy model
772  WifiRadioEnergyModelHelper radioEnergyHelper;
773  // set VariableLoadTestIDLE current, which will be the constant load
774  radioEnergyHelper.Set ("IdleCurrentA", DoubleValue (load));
775  // install on node
776  DeviceEnergyModelContainer deviceModels = radioEnergyHelper.Install (devices, sources);
777 
778  // run simulation
779  Simulator::Stop (Seconds (70000.0));
780  Simulator::Run ();
781 
782  Time actualLifetime;
783  Ptr<RvBatteryModel> srcPtr = DynamicCast<RvBatteryModel> (sources.Get (0));
784  actualLifetime = srcPtr->GetLifetime ();
785 
786  NS_LOG_DEBUG ("Expected lifetime = " << expLifetime.As (Time::S));
787  NS_LOG_DEBUG ("Actual lifetime = " << actualLifetime.As (Time::S));
788 
790 
791  if (actualLifetime != expLifetime)
792  {
793  std::cerr << "ConstantLoadTest: Incorrect lifetime for load " << load << std::endl;
794  return true;
795  }
796 
797  return false; // error free
798 }
799 
800 bool
801 BatteryLifetimeTest::VariableLoadTest (std::vector<double> loads,
802  std::vector<Time> timeStamps,
803  Time expLifetime)
804 {
805  NS_ASSERT (loads.size () == timeStamps.size ());
806 
807  // create single node
808  NodeContainer c;
809  c.Create (1);
810 
811  std::string phyMode ("DsssRate1Mbps");
812 
813  // disable fragmentation for frames below 2200 bytes
814  Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold",
815  StringValue ("2200"));
816  // turn off RTS/CTS for frames below 2200 bytes
817  Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold",
818  StringValue ("2200"));
819  // Fix non-unicast data rate to be the same as that of unicast
820  Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode",
821  StringValue (phyMode));
822 
823  // install YansWifiPhy
825  wifi.SetStandard (WIFI_STANDARD_80211b);
826 
827  YansWifiPhyHelper wifiPhy;
828  /*
829  * This is one parameter that matters when using FixedRssLossModel, set it to
830  * zero; otherwise, gain will be added.
831  */
832  wifiPhy.Set ("RxGain", DoubleValue (0));
833  // ns-3 supports RadioTap and Prism tracing extensions for 802.11b
835 
836  YansWifiChannelHelper wifiChannel;
837  wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
838  wifiPhy.SetChannel (wifiChannel.Create ());
839 
840  // Add a MAC and disable rate control
841  WifiMacHelper wifiMac;
842  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
843  "DataMode", StringValue (phyMode),
844  "ControlMode", StringValue (phyMode));
845  // Set it to ad-hoc mode
846  wifiMac.SetType ("ns3::AdhocWifiMac");
847  NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, c);
848 
849  // Create and install battery model and device models
850  // RV battery model
851  RvBatteryModelHelper rvModelHelper;
852  // Set alpha & beta values
853  rvModelHelper.Set ("RvBatteryModelAlphaValue", DoubleValue (m_alpha));
854  rvModelHelper.Set ("RvBatteryModelBetaValue", DoubleValue (m_beta));
855  rvModelHelper.Set ("RvBatteryModelLowBatteryThreshold", DoubleValue (0.0));
856  // install source
857  EnergySourceContainer sources = rvModelHelper.Install (c);
858  // device energy model
859  WifiRadioEnergyModelHelper radioEnergyHelper;
860  // set VariableLoadTestIDLE current, which will be the constant load
861  radioEnergyHelper.Set ("IdleCurrentA", DoubleValue (loads[0]));
862  // install on node
863  DeviceEnergyModelContainer deviceModels = radioEnergyHelper.Install (devices, sources);
864 
865 
866  Ptr<WifiRadioEnergyModel> wifiDevicePtr = DynamicCast<WifiRadioEnergyModel> (deviceModels.Get (0));
867  // schedule load change events
868  for (uint32_t i = 1; i < loads.size (); i++)
869  {
871  wifiDevicePtr, loads[i]);
872  }
873 
874  // run simulation
875  Simulator::Stop (Seconds (70000.0));
876  Simulator::Run ();
877 
878  Time actualLifetime;
879  Ptr<RvBatteryModel> srcPtr = DynamicCast<RvBatteryModel> (sources.Get (0));
880  actualLifetime = srcPtr->GetLifetime ();
881 
882  NS_LOG_DEBUG ("Expected lifetime = " << expLifetime.As (Time::S));
883  NS_LOG_DEBUG ("Actual lifetime = " << actualLifetime.As (Time::S));
884  NS_LOG_DEBUG ("Difference = " << (expLifetime - actualLifetime).As (Time::S));
885 
887 
888  // error tolerance = 120s
889  if (Abs (actualLifetime - expLifetime) > Seconds (120))
890  {
891  std::cerr << "VariableLoadTest: Incorrect lifetime." << std::endl;
892  return true;
893  }
894 
895  return false; // error free
896 }
897 
This example was originally devised as a test, then it was converted to an example.
void CreateLoadProfiles(void)
Creates load profiles according to D.
bool ConstantLoadTest(double load, Time expLifetime)
double m_beta
Beta parameter of the battery model.
bool VariableLoadTest(std::vector< double > loads, std::vector< Time > timeStamps, Time expLifetime)
double m_alpha
Alpha parameter of the battery model.
std::vector< LoadProfile > m_loadProfiles
Load profiles.
Parse command-line arguments.
Definition: command-line.h:229
Holds a vector of ns3::DeviceEnergyModel pointers.
Ptr< DeviceEnergyModel > Get(uint32_t i) const
Get the i-th Ptr<DeviceEnergyModel> stored in this container.
DeviceEnergyModelContainer Install(Ptr< NetDevice > device, Ptr< EnergySource > source) const
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
Holds a vector of ns3::EnergySource pointers.
Ptr< EnergySource > Get(uint32_t i) const
Get the i-th Ptr<EnergySource> stored in this container.
EnergySourceContainer Install(Ptr< Node > node) const
holds a vector of ns3::NetDevice pointers
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
Creates a RvBatteryModel object.
void Set(std::string name, const AttributeValue &v)
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:180
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:136
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
Hold variables of type string.
Definition: string.h:41
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
@ S
second
Definition: nstime.h:114
TimeWithUnit As(const enum Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:418
helps to create WifiNetDevice objects
Definition: wifi-helper.h:274
create MAC layers for a ns3::WifiNetDevice.
void SetType(std::string type, Args &&... args)
void SetPcapDataLinkType(SupportedPcapDataLinkTypes dlt)
Set the data link type of PCAP traces to be used.
Definition: wifi-helper.cc:518
void Set(std::string name, const AttributeValue &v)
Definition: wifi-helper.cc:154
@ DLT_IEEE802_11_RADIO
Include Radiotap link layer information.
Definition: wifi-helper.h:126
Assign WifiRadioEnergyModel to wifi devices.
void Set(std::string name, const AttributeValue &v) override
void SetIdleCurrentA(double idleCurrentA)
Sets idle current in Amperes.
manage and create wifi channel objects for the YANS model.
void SetPropagationDelay(std::string name, std::string n0="", const AttributeValue &v0=EmptyAttributeValue(), std::string n1="", const AttributeValue &v1=EmptyAttributeValue(), std::string n2="", const AttributeValue &v2=EmptyAttributeValue(), std::string n3="", const AttributeValue &v3=EmptyAttributeValue(), std::string n4="", const AttributeValue &v4=EmptyAttributeValue(), std::string n5="", const AttributeValue &v5=EmptyAttributeValue(), std::string n6="", const AttributeValue &v6=EmptyAttributeValue(), std::string n7="", const AttributeValue &v7=EmptyAttributeValue())
Ptr< YansWifiChannel > Create(void) const
Make it easy to create and manage PHY objects for the YANS model.
void SetChannel(Ptr< YansWifiChannel > channel)
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
int64x64_t Abs(const int64x64_t &value)
Absolute value.
Definition: int64x64.h:205
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
@ WIFI_STANDARD_80211b
devices
Definition: first.py:39
Every class exported by the ns3 library is enclosed in the ns3 namespace.
cmd
Definition: second.py:35
wifi
Definition: third.py:96
Load profile of the battery.
std::vector< Time > timeStamps
Timestamps container.
std::vector< double > loads
Loads container.
Time dualFoilLifeTime
Expected lifetime for a Dualfoil battery.
Time itsyLifetime
Expected lifetime for an ITSY battery.