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