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