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