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