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