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