A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ns2-mobility-helper.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007 INRIA
3 * 2009,2010 Contributors
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
8 * Contributors: Thomas Waldecker <twaldecker@rocketmail.com>
9 * Martín Giachino <martin.giachino@gmail.com>
10 *
11 * Brief description: Implementation of a ns2 movement trace file reader.
12 *
13 * This implementation is based on the ns2 movement documentation of ns2
14 * as described in http://www.isi.edu/nsnam/ns/doc/node172.html
15 *
16 * Valid trace files use the following ns2 statements:
17 *
18 * $node set X_ x1
19 * $node set Y_ y1
20 * $node set Z_ z1
21 * $ns at $time $node setdest x2 y2 speed
22 * $ns at $time $node set X_ x1
23 * $ns at $time $node set Y_ Y1
24 * $ns at $time $node set Z_ Z1
25 *
26 */
27
28#include "ns2-mobility-helper.h"
29
30#include "ns3/constant-velocity-mobility-model.h"
31#include "ns3/log.h"
32#include "ns3/node-list.h"
33#include "ns3/node.h"
34#include "ns3/simulator.h"
35
36#include <fstream>
37#include <map>
38#include <sstream>
39
40namespace ns3
41{
42
43NS_LOG_COMPONENT_DEFINE("Ns2MobilityHelper");
44
45// Constants definitions
46#define NS2_AT "at"
47#define NS2_X_COORD "X_"
48#define NS2_Y_COORD "Y_"
49#define NS2_Z_COORD "Z_"
50#define NS2_SETDEST "setdest"
51#define NS2_SET "set"
52#define NS2_NS_SCH "$ns_"
53
54/**
55 * Type to maintain line parsed and its values
56 */
58{
59 std::vector<std::string> tokens; //!< tokens from a line
60 std::vector<int> ivals; //!< int values for each tokens
61 std::vector<bool> has_ival; //!< points if a tokens has an int value
62 std::vector<double> dvals; //!< double values for each tokens
63 std::vector<bool> has_dval; //!< points if a tokens has a double value
64 std::vector<std::string> svals; //!< string value for each token
65};
66
67/**
68 * Keeps last movement schedule. If new movement occurs during
69 * a current one, node stopping must be cancels (stored in a proper
70 * event ID), actually reached point must be calculated and new
71 * velocity must be calculated in accordance with actually reached
72 * destination.
73 */
75{
76 Vector m_startPosition; //!< Start position of last movement
77 Vector m_speed; //!< Speed of the last movement (needed to derive reached destination at next
78 //!< schedule = start + velocity * actuallyTravelled)
79 Vector m_finalPosition; //!< Final destination to be reached before next schedule. Replaced with
80 //!< actually reached if needed.
81 EventId m_stopEvent; //!< Event scheduling node's stop. May be canceled if needed.
82 double m_travelStartTime; //!< Travel start time is needed to calculate actually traveled time
83 double m_targetArrivalTime; //!< When a station arrives to a destination
84
86 : m_startPosition(Vector(0, 0, 0)),
87 m_speed(Vector(0, 0, 0)),
88 m_finalPosition(Vector(0, 0, 0)),
91 {
92 }
93};
94
95/**
96 * Parses a line of ns2 mobility
97 * @param str the string to parse
98 * @returns The parsed line
99 */
100static ParseResult ParseNs2Line(const std::string& str);
101
102/**
103 * Put out blank spaces at the start and end of a line
104 * @param str input line
105 * @returns the line trimmed
106 */
107static std::string TrimNs2Line(const std::string& str);
108
109/**
110 * Checks if a string represents a number or it has others characters than digits and point.
111 * @param s the string to check
112 * @returns true if the string represents a number
113 */
114static bool IsNumber(const std::string& s);
115
116/**
117 * Check if s string represents a numeric value
118 * @param str string to check
119 * @param ret numeric value to return
120 * @return true if string represents a numeric value
121 */
122template <class T>
123static bool IsVal(const std::string& str, T& ret);
124
125/**
126 * Checks if the value between brackets is a correct nodeId number
127 * @param str string to check
128 * @returns true if the string represents a nodeId number
129 */
130static bool HasNodeIdNumber(std::string str);
131
132/**
133 * Gets nodeId number in string format from the string like $node_(4)
134 * @param str string to de-tokenize
135 * @returns A string with the nodeId number
136 */
137static std::string GetNodeIdFromToken(std::string str);
138
139/**
140 * Get node id number in int format
141 * @param pr the ParseResult to analyze
142 * @returns the node ID (as an int)
143 */
144static int GetNodeIdInt(ParseResult pr);
145
146/**
147 * Get node id number in string format
148 * @param pr the ParseResult to analyze
149 * @returns the node ID (as a string)
150 */
151static std::string GetNodeIdString(ParseResult pr);
152
153/**
154 * Add one coord to a vector position
155 * @param actPos actual position (overwritten)
156 * @param coord coordinate (x, y, or z)
157 * @param value value of the coordinate
158 * @return The vector of the position
159 */
160static Vector SetOneInitialCoord(Vector actPos, std::string& coord, double value);
161
162/**
163 * Check if this corresponds to a line like this: $node_(0) set X_ 123
164 * @param pr the ParseResult to analyze
165 * @returns true if the ParseResult looks like a coordinate without a scheduled time
166 */
167static bool IsSetInitialPos(ParseResult pr);
168
169/**
170 * Check if this corresponds to a line like this: $ns_ at 1 "$node_(0) setdest 2 3 4"
171 * @param pr the ParseResult to analyze
172 * @returns true if the ParseResult looks like a coordinate with a scheduled time and destination
173 */
174static bool IsSchedSetPos(ParseResult pr);
175
176/**
177 * Check if this corresponds to a line like this: $ns_ at 1 "$node_(0) set X_ 2"
178 * @param pr the ParseResult to analyze
179 * @returns true if the ParseResult looks like a coordinate with a scheduled time
180 */
181static bool IsSchedMobilityPos(ParseResult pr);
182
183/**
184 * Set waypoints and speed for movement.
185 * @param model mobility model
186 * @param lastPos last position
187 * @param at initial movement time
188 * @param xFinalPosition final position (X axis)
189 * @param yFinalPosition final position (Y axis)
190 * @param speed movement speed
191 * @returns A descriptor of the movement
192 */
193static DestinationPoint SetMovement(Ptr<ConstantVelocityMobilityModel> model,
194 Vector lastPos,
195 double at,
196 double xFinalPosition,
197 double yFinalPosition,
198 double speed);
199
200/**
201 * Set initial position for a node
202 * @param model mobility model
203 * @param coord coordinate (x, y, or z)
204 * @param coordVal value of the coordinate
205 * @return The vector of the position
206 */
207static Vector SetInitialPosition(Ptr<ConstantVelocityMobilityModel> model,
208 std::string coord,
209 double coordVal);
210
211/**
212 * Schedule a set of position for a node
213 * @param model mobility model
214 * @param at initial movement time
215 * @param coord coordinate (x, y, or z)
216 * @param coordVal value of the coordinate
217 * @return The vector of the position at the given time
218 */
219static Vector SetSchedPosition(Ptr<ConstantVelocityMobilityModel> model,
220 double at,
221 std::string coord,
222 double coordVal);
223
225 : m_filename(filename)
226{
227 std::ifstream file(m_filename, std::ios::in);
228 if (!(file.is_open()))
229 {
230 NS_FATAL_ERROR("Could not open trace file " << m_filename
231 << " for reading, aborting here \n");
232 }
233}
234
236Ns2MobilityHelper::GetMobilityModel(std::string idString, const ObjectStore& store) const
237{
238 std::istringstream iss;
239 iss.str(idString);
240 uint32_t id(0);
241 iss >> id;
242 Ptr<Object> object = store.Get(id);
243 if (!object)
244 {
245 return nullptr;
246 }
248 if (!model)
249 {
251 object->AggregateObject(model);
252 }
253 return model;
254}
255
256void
258{
259 std::map<int, DestinationPoint> last_pos; // Stores previous movement scheduled for each node
260
261 //*****************************************************************
262 // Parse the file the first time to get the initial node positions.
263 //*****************************************************************
264
265 // Look through the whole the file for the the initial node
266 // positions to make this helper robust to handle trace files with
267 // the initial node positions at the end.
268 std::ifstream file(m_filename, std::ios::in);
269 if (file.is_open())
270 {
271 while (!file.eof())
272 {
273 int iNodeId = 0;
274 std::string nodeId;
275 std::string line;
276
277 getline(file, line);
278
279 // ignore empty lines
280 if (line.empty())
281 {
282 continue;
283 }
284
285 ParseResult pr = ParseNs2Line(line); // Parse line and obtain tokens
286
287 // Check if the line corresponds with setting the initial
288 // node positions
289 if (pr.tokens.size() != 4)
290 {
291 continue;
292 }
293
294 // Get the node Id
295 nodeId = GetNodeIdString(pr);
296 iNodeId = GetNodeIdInt(pr);
297 if (iNodeId == -1)
298 {
299 NS_LOG_ERROR("Node number couldn't be obtained (corrupted file?): " << line
300 << "\n");
301 continue;
302 }
303
304 // get mobility model of node
306
307 // if model not exists, continue
308 if (!model)
309 {
310 NS_LOG_ERROR("Unknown node ID (corrupted file?): " << nodeId << "\n");
311 continue;
312 }
313
314 /*
315 * In this case a initial position is being seted
316 * line like $node_(0) set X_ 151.05190721688197
317 */
318 if (IsSetInitialPos(pr))
319 {
320 DestinationPoint point;
321 // coord coord value
322 point.m_finalPosition = SetInitialPosition(model, pr.tokens[2], pr.dvals[3]);
323 last_pos[iNodeId] = point;
324
325 // Log new position
326 NS_LOG_DEBUG("Positions after parse for node "
327 << iNodeId << " " << nodeId
328 << " position = " << last_pos[iNodeId].m_finalPosition);
329 }
330 }
331 file.close();
332 }
333
334 //*****************************************************************
335 // Parse the file a second time to get the rest of its values
336 //*****************************************************************
337
338 // The reason the file is parsed again is to make this helper robust
339 // to handle trace files with the initial node positions at the end.
340 file.open(m_filename, std::ios::in);
341 if (file.is_open())
342 {
343 while (!file.eof())
344 {
345 int iNodeId = 0;
346 std::string nodeId;
347 std::string line;
348
349 getline(file, line);
350
351 // ignore empty lines
352 if (line.empty())
353 {
354 continue;
355 }
356
357 ParseResult pr = ParseNs2Line(line); // Parse line and obtain tokens
358
359 // Check if the line corresponds with one of the three types of line
360 if (pr.tokens.size() != 4 && pr.tokens.size() != 7 && pr.tokens.size() != 8)
361 {
362 NS_LOG_ERROR("Line has not correct number of parameters (corrupted file?): "
363 << line << "\n");
364 continue;
365 }
366
367 // Get the node Id
368 nodeId = GetNodeIdString(pr);
369 iNodeId = GetNodeIdInt(pr);
370 if (iNodeId == -1)
371 {
372 NS_LOG_ERROR("Node number couldn't be obtained (corrupted file?): " << line
373 << "\n");
374 continue;
375 }
376
377 // get mobility model of node
379
380 // if model not exists, continue
381 if (!model)
382 {
383 NS_LOG_ERROR("Unknown node ID (corrupted file?): " << nodeId << "\n");
384 continue;
385 }
386
387 /*
388 * In this case a initial position is being seted
389 * line like $node_(0) set X_ 151.05190721688197
390 */
391 if (IsSetInitialPos(pr))
392 {
393 // This is the second time this file has been parsed,
394 // and the initial node positions were already set the
395 // first time. So, do nothing this time with this line.
396 continue;
397 }
398
399 else // NOW EVENTS TO BE SCHEDULED
400 {
401 // This is a scheduled event, so time at should be present
402 double at;
403
404 if (!IsNumber(pr.tokens[2]))
405 {
406 NS_LOG_WARN("Time is not a number: " << pr.tokens[2]);
407 continue;
408 }
409
410 at = pr.dvals[2]; // set time at
411
412 if (at < 0)
413 {
414 NS_LOG_WARN("Time is less than cero: " << at);
415 continue;
416 }
417
418 /*
419 * In this case a new waypoint is added
420 * line like $ns_ at 1 "$node_(0) setdest 2 3 4"
421 */
422 if (IsSchedMobilityPos(pr))
423 {
424 if (last_pos[iNodeId].m_targetArrivalTime > at)
425 {
426 NS_LOG_LOGIC("Did not reach a destination! stoptime = "
427 << last_pos[iNodeId].m_targetArrivalTime << ", at = " << at);
428 double actuallytraveled = at - last_pos[iNodeId].m_travelStartTime;
429 Vector reached = Vector(last_pos[iNodeId].m_startPosition.x +
430 last_pos[iNodeId].m_speed.x * actuallytraveled,
431 last_pos[iNodeId].m_startPosition.y +
432 last_pos[iNodeId].m_speed.y * actuallytraveled,
433 0);
434 NS_LOG_LOGIC("Final point = " << last_pos[iNodeId].m_finalPosition
435 << ", actually reached = " << reached);
436 last_pos[iNodeId].m_stopEvent.Cancel();
437 last_pos[iNodeId].m_finalPosition = reached;
438 }
439 // last position time X coord Y
440 // coord velocity
441 last_pos[iNodeId] = SetMovement(model,
442 last_pos[iNodeId].m_finalPosition,
443 at,
444 pr.dvals[5],
445 pr.dvals[6],
446 pr.dvals[7]);
447
448 // Log new position
449 NS_LOG_DEBUG("Positions after parse for node "
450 << iNodeId << " " << nodeId
451 << " position =" << last_pos[iNodeId].m_finalPosition);
452 }
453
454 /*
455 * Scheduled set position
456 * line like $ns_ at 4.634906291962 "$node_(0) set X_ 28.675920486450"
457 */
458 else if (IsSchedSetPos(pr))
459 {
460 // time coordinate coord value
461 last_pos[iNodeId].m_finalPosition =
462 SetSchedPosition(model, at, pr.tokens[5], pr.dvals[6]);
463 if (last_pos[iNodeId].m_targetArrivalTime > at)
464 {
465 last_pos[iNodeId].m_stopEvent.Cancel();
466 }
467 last_pos[iNodeId].m_targetArrivalTime = at;
468 last_pos[iNodeId].m_travelStartTime = at;
469 // Log new position
470 NS_LOG_DEBUG("Positions after parse for node "
471 << iNodeId << " " << nodeId
472 << " position =" << last_pos[iNodeId].m_finalPosition);
473 }
474 else
475 {
476 NS_LOG_WARN("Format Line is not correct: " << line << "\n");
477 }
478 }
479 }
480 file.close();
481 }
482}
483
485ParseNs2Line(const std::string& str)
486{
487 ParseResult ret;
488 std::istringstream s;
489 std::string line;
490
491 // ignore comments (#)
492 size_t pos_sharp = str.find_first_of('#');
493 if (pos_sharp != std::string::npos)
494 {
495 line = str.substr(0, pos_sharp);
496 }
497 else
498 {
499 line = str;
500 }
501
502 line = TrimNs2Line(line);
503
504 // If line hasn't a correct node Id
505 if (!HasNodeIdNumber(line))
506 {
507 NS_LOG_WARN("Line has no node Id: " << line);
508 return ret;
509 }
510
511 s.str(line);
512
513 while (!s.eof())
514 {
515 std::string x;
516 s >> x;
517 if (x.empty())
518 {
519 continue;
520 }
521 ret.tokens.push_back(x);
522 int ii(0);
523 double d(0);
524 if (HasNodeIdNumber(x))
525 {
526 x = GetNodeIdFromToken(x);
527 }
528 ret.has_ival.push_back(IsVal<int>(x, ii));
529 ret.ivals.push_back(ii);
530 ret.has_dval.push_back(IsVal<double>(x, d));
531 ret.dvals.push_back(d);
532 ret.svals.push_back(x);
533 }
534
535 size_t tokensLength = ret.tokens.size(); // number of tokens in line
536 size_t lasTokenLength = ret.tokens[tokensLength - 1].size(); // length of the last token
537
538 // if it is a scheduled set _[XYZ] or a setdest I need to remove the last "
539 // and re-calculate values
540 if ((tokensLength == 7 || tokensLength == 8) &&
541 (ret.tokens[tokensLength - 1][lasTokenLength - 1] == '"'))
542 {
543 // removes " from the last position
544 ret.tokens[tokensLength - 1] = ret.tokens[tokensLength - 1].substr(0, lasTokenLength - 1);
545
546 std::string x;
547 x = ret.tokens[tokensLength - 1];
548
549 if (HasNodeIdNumber(x))
550 {
551 x = GetNodeIdFromToken(x);
552 }
553
554 // Re calculate values
555 int ii(0);
556 double d(0);
557 ret.has_ival[tokensLength - 1] = IsVal<int>(x, ii);
558 ret.ivals[tokensLength - 1] = ii;
559 ret.has_dval[tokensLength - 1] = IsVal<double>(x, d);
560 ret.dvals[tokensLength - 1] = d;
561 ret.svals[tokensLength - 1] = x;
562 }
563 else if ((tokensLength == 9 && ret.tokens[tokensLength - 1] == "\"") ||
564 (tokensLength == 8 && ret.tokens[tokensLength - 1] == "\""))
565 {
566 // if the line has the " character in this way: $ns_ at 1 "$node_(0) setdest 2 2 1 "
567 // or in this: $ns_ at 4 "$node_(0) set X_ 2 " we need to ignore this last token
568
569 ret.tokens.erase(ret.tokens.begin() + tokensLength - 1);
570 ret.has_ival.erase(ret.has_ival.begin() + tokensLength - 1);
571 ret.ivals.erase(ret.ivals.begin() + tokensLength - 1);
572 ret.has_dval.erase(ret.has_dval.begin() + tokensLength - 1);
573 ret.dvals.erase(ret.dvals.begin() + tokensLength - 1);
574 ret.svals.erase(ret.svals.begin() + tokensLength - 1);
575 }
576
577 return ret;
578}
579
580std::string
581TrimNs2Line(const std::string& s)
582{
583 std::string ret = s;
584
585 while (!ret.empty() && isblank(ret[0]))
586 {
587 ret.erase(0, 1); // Removes blank spaces at the beginning of the line
588 }
589
590 while (!ret.empty() && (isblank(ret[ret.size() - 1]) || (ret[ret.size() - 1] == ';')))
591 {
592 ret.erase(ret.size() - 1, 1); // Removes blank spaces from at end of line
593 }
594
595 return ret;
596}
597
598bool
599IsNumber(const std::string& s)
600{
601 char* endp;
602 strtod(s.c_str(), &endp);
603 return endp == s.c_str() + s.size();
604}
605
606template <class T>
607bool
608IsVal(const std::string& str, T& ret)
609{
610 if (str.empty())
611 {
612 return false;
613 }
614
615 if (IsNumber(str))
616 {
617 std::istringstream s(str);
618 s >> ret;
619 return true;
620 }
621 else
622 {
623 return false;
624 }
625}
626
627bool
628HasNodeIdNumber(std::string str)
629{
630 // find brackets
631 std::string::size_type startNodeId = str.find_first_of('('); // index of left bracket
632 std::string::size_type endNodeId = str.find_first_of(')'); // index of right bracket
633
634 // Get de nodeId in a string and in a int value
635 std::string nodeId; // node id
636
637 // if no brackets, continue!
638 if (startNodeId == std::string::npos || endNodeId == std::string::npos)
639 {
640 return false;
641 }
642
643 nodeId = str.substr(startNodeId + 1, endNodeId - (startNodeId + 1)); // set node id
644
645 // is number is integer is not negative
646 return IsNumber(nodeId) && nodeId.find_first_of('.') == std::string::npos && nodeId[0] != '-';
647}
648
649std::string
650GetNodeIdFromToken(std::string str)
651{
652 if (HasNodeIdNumber(str))
653 {
654 // find brackets
655 std::string::size_type startNodeId = str.find_first_of('('); // index of left bracket
656 std::string::size_type endNodeId = str.find_first_of(')'); // index of right bracket
657
658 return str.substr(startNodeId + 1, endNodeId - (startNodeId + 1)); // set node id
659 }
660 else
661 {
662 return "";
663 }
664}
665
666int
668{
669 int result = -1;
670 switch (pr.tokens.size())
671 {
672 case 4: // line like $node_(0) set X_ 11
673 result = pr.ivals[0];
674 break;
675 case 7: // line like $ns_ at 4 "$node_(0) set X_ 28"
676 case 8: // line like $ns_ at 1 "$node_(0) setdest 2 3 4"
677 result = pr.ivals[3];
678 break;
679 default:
680 result = -1;
681 }
682 return result;
683}
684
685// Get node id number in string format
686std::string
688{
689 switch (pr.tokens.size())
690 {
691 case 4: // line like $node_(0) set X_ 11
692 return pr.svals[0];
693 case 7: // line like $ns_ at 4 "$node_(0) set X_ 28"
694 case 8: // line like $ns_ at 1 "$node_(0) setdest 2 3 4"
695 return pr.svals[3];
696 default:
697 return "";
698 }
699}
700
701Vector
702SetOneInitialCoord(Vector position, std::string& coord, double value)
703{
704 // set the position for the coord.
705 if (coord == NS2_X_COORD)
706 {
707 position.x = value;
708 NS_LOG_DEBUG("X=" << value);
709 }
710 else if (coord == NS2_Y_COORD)
711 {
712 position.y = value;
713 NS_LOG_DEBUG("Y=" << value);
714 }
715 else if (coord == NS2_Z_COORD)
716 {
717 position.z = value;
718 NS_LOG_DEBUG("Z=" << value);
719 }
720 return position;
721}
722
723bool
725{
726 // number of tokens has $node_( ? has "set" has
727 // double for position?
728 return pr.tokens.size() == 4 && HasNodeIdNumber(pr.tokens[0]) && pr.tokens[1] == NS2_SET &&
729 pr.has_dval[3]
730 // coord name is X_, Y_ or Z_ ?
731 && (pr.tokens[2] == NS2_X_COORD || pr.tokens[2] == NS2_Y_COORD ||
732 pr.tokens[2] == NS2_Z_COORD);
733}
734
735bool
737{
738 // correct number of tokens, has $ns_ and at
739 return pr.tokens.size() == 7 && pr.tokens[0] == NS2_NS_SCH && pr.tokens[1] == NS2_AT &&
740 pr.tokens[4] == NS2_SET && pr.has_dval[2] &&
741 pr.has_dval[3] // has set and double value for time and nodeid
742 && (pr.tokens[5] == NS2_X_COORD || pr.tokens[5] == NS2_Y_COORD ||
743 pr.tokens[5] == NS2_Z_COORD) // has X_, Y_ or Z_?
744 && pr.has_dval[2]; // time is a number
745}
746
747bool
749{
750 // number of tokens and has $ns_ and has at
751 return pr.tokens.size() == 8 && pr.tokens[0] == NS2_NS_SCH &&
752 pr.tokens[1] == NS2_AT
753 // time x coord y coord velocity are numbers?
754 && pr.has_dval[2] && pr.has_dval[5] && pr.has_dval[6] && pr.has_dval[7] &&
755 pr.tokens[4] == NS2_SETDEST; // and has setdest
756}
757
758DestinationPoint
760 Vector last_pos,
761 double at,
762 double xFinalPosition,
763 double yFinalPosition,
764 double speed)
765{
766 DestinationPoint retval;
767 retval.m_startPosition = last_pos;
768 retval.m_finalPosition = last_pos;
769 retval.m_travelStartTime = at;
770 retval.m_targetArrivalTime = at;
771
772 if (speed == 0)
773 {
774 // We have to maintain last position, and stop the movement
777 model,
778 Vector(0, 0, 0));
779 return retval;
780 }
781 if (speed > 0)
782 {
783 // first calculate the time; time = distance / speed
784 double time = std::sqrt(std::pow(xFinalPosition - retval.m_finalPosition.x, 2) +
785 std::pow(yFinalPosition - retval.m_finalPosition.y, 2)) /
786 speed;
787 NS_LOG_DEBUG("at=" << at << " time=" << time);
788 if (time == 0)
789 {
790 return retval;
791 }
792 // now calculate the xSpeed = distance / time
793 double xSpeed = (xFinalPosition - retval.m_finalPosition.x) / time;
794 double ySpeed = (yFinalPosition - retval.m_finalPosition.y) / time; // & same with ySpeed
795 retval.m_speed = Vector(xSpeed, ySpeed, 0);
796
797 // quick and dirty set zSpeed = 0
798 double zSpeed = 0;
799
800 NS_LOG_DEBUG("Calculated Speed: X=" << xSpeed << " Y=" << ySpeed << " Z=" << zSpeed);
801
802 // Set the Values
805 model,
806 Vector(xSpeed, ySpeed, zSpeed));
807 retval.m_stopEvent = Simulator::Schedule(Seconds(at + time),
809 model,
810 Vector(0, 0, 0));
811 retval.m_finalPosition.x += xSpeed * time;
812 retval.m_finalPosition.y += ySpeed * time;
813 retval.m_targetArrivalTime += time;
814 }
815 return retval;
816}
817
818Vector
819SetInitialPosition(Ptr<ConstantVelocityMobilityModel> model, std::string coord, double coordVal)
820{
821 model->SetPosition(SetOneInitialCoord(model->GetPosition(), coord, coordVal));
822
823 Vector position;
824 position.x = model->GetPosition().x;
825 position.y = model->GetPosition().y;
826 position.z = model->GetPosition().z;
827
828 return position;
829}
830
831// Schedule a set of position for a node
832Vector
834 double at,
835 std::string coord,
836 double coordVal)
837{
838 // update position
839 model->SetPosition(SetOneInitialCoord(model->GetPosition(), coord, coordVal));
840
841 Vector position;
842 position.x = model->GetPosition().x;
843 position.y = model->GetPosition().y;
844 position.z = model->GetPosition().z;
845
846 // Schedule next positions
848
849 return position;
850}
851
852void
857
858} // namespace ns3
Mobility model for which the current speed does not change once it has been set and until it is set a...
An identifier for simulation events.
Definition event-id.h:44
void SetPosition(const Vector &position)
static Iterator Begin()
Definition node-list.cc:226
static Iterator End()
Definition node-list.cc:233
a class to hold input objects internally
virtual Ptr< Object > Get(uint32_t i) const =0
Return ith object in store.
void ConfigNodesMovements(const ObjectStore &store) const
Parses ns-2 mobility file to create ns-3 mobility events.
void Install() const
Read the ns2 trace file and configure the movement patterns of all nodes contained in the global ns3:...
std::string m_filename
filename of file containing ns-2 mobility trace
Ptr< ConstantVelocityMobilityModel > GetMobilityModel(std::string idString, const ObjectStore &store) const
Get or create a ConstantVelocityMobilityModel corresponding to idString.
Ns2MobilityHelper(std::string filename)
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:67
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:561
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition log.h:243
#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
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition log.h:250
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1369
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static bool IsSchedMobilityPos(ParseResult pr)
Check if this corresponds to a line like this: $ns_ at 1 "$node_(0) set X_ 2".
static bool IsNumber(const std::string &s)
Checks if a string represents a number or it has others characters than digits and point.
static std::string TrimNs2Line(const std::string &str)
Put out blank spaces at the start and end of a line.
static ParseResult ParseNs2Line(const std::string &str)
Parses a line of ns2 mobility.
static Vector SetOneInitialCoord(Vector actPos, std::string &coord, double value)
Add one coord to a vector position.
static bool IsSetInitialPos(ParseResult pr)
Check if this corresponds to a line like this: $node_(0) set X_ 123.
static std::string GetNodeIdFromToken(std::string str)
Gets nodeId number in string format from the string like $node_(4)
static bool HasNodeIdNumber(std::string str)
Checks if the value between brackets is a correct nodeId number.
static Vector SetInitialPosition(Ptr< ConstantVelocityMobilityModel > model, std::string coord, double coordVal)
Set initial position for a node.
static DestinationPoint SetMovement(Ptr< ConstantVelocityMobilityModel > model, Vector lastPos, double at, double xFinalPosition, double yFinalPosition, double speed)
Set waypoints and speed for movement.
static Vector SetSchedPosition(Ptr< ConstantVelocityMobilityModel > model, double at, std::string coord, double coordVal)
Schedule a set of position for a node.
static bool IsVal(const std::string &str, T &ret)
Check if s string represents a numeric value.
static bool IsSchedSetPos(ParseResult pr)
Check if this corresponds to a line like this: $ns_ at 1 "$node_(0) setdest 2 3 4".
static int GetNodeIdInt(ParseResult pr)
Get node id number in int format.
static std::string GetNodeIdString(ParseResult pr)
Get node id number in string format.
#define NS2_AT
#define NS2_Y_COORD
#define NS2_SETDEST
#define NS2_Z_COORD
#define NS2_SET
#define NS2_NS_SCH
#define NS2_X_COORD
Keeps last movement schedule.
double m_travelStartTime
Travel start time is needed to calculate actually traveled time.
EventId m_stopEvent
Event scheduling node's stop.
Vector m_finalPosition
Final destination to be reached before next schedule.
double m_targetArrivalTime
When a station arrives to a destination.
Vector m_speed
Speed of the last movement (needed to derive reached destination at next schedule = start + velocity ...
Vector m_startPosition
Start position of last movement.
Type to maintain line parsed and its values.
std::vector< double > dvals
double values for each tokens
std::vector< std::string > svals
string value for each token
std::vector< std::string > tokens
tokens from a line
std::vector< int > ivals
int values for each tokens
std::vector< bool > has_ival
points if a tokens has an int value
std::vector< bool > has_dval
points if a tokens has a double value