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/unused.h"
46 #include "ns3/simulator.h"
47 #include "ns3/node-list.h"
48 #include "ns3/node.h"
49 #include "ns3/constant-velocity-mobility-model.h"
50 #include "ns2-mobility-helper.h"
51 
52 namespace ns3 {
53 
54 NS_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 
71 {
72  std::vector<std::string> tokens;
73  std::vector<int> ivals;
74  std::vector<bool> has_ival;
75  std::vector<double> dvals;
76  std::vector<bool> has_dval;
77  std::vector<std::string> svals;
78 };
87 {
88  Vector m_startPosition;
89  Vector m_speed;
90  Vector m_finalPosition;
95  m_startPosition (Vector (0,0,0)),
96  m_speed (Vector (0,0,0)),
97  m_finalPosition (Vector (0,0,0)),
100  {};
101 };
102 
103 
109 static ParseResult ParseNs2Line (const std::string& str);
110 
116 static std::string TrimNs2Line (const std::string& str);
117 
123 static bool IsNumber (const std::string& s);
124 
131 template<class T>
132 static bool IsVal (const std::string& str, T& ret);
133 
139 static bool HasNodeIdNumber (std::string str);
140 
146 static std::string GetNodeIdFromToken (std::string str);
147 
153 static int GetNodeIdInt (ParseResult pr);
154 
160 static std::string GetNodeIdString (ParseResult pr);
161 
169 static Vector SetOneInitialCoord (Vector actPos, std::string& coord, double value);
170 
176 static bool IsSetInitialPos (ParseResult pr);
177 
183 static bool IsSchedSetPos (ParseResult pr);
184 
190 static bool IsSchedMobilityPos (ParseResult pr);
191 
202 static DestinationPoint SetMovement (Ptr<ConstantVelocityMobilityModel> model, Vector lastPos, double at,
203  double xFinalPosition, double yFinalPosition, double speed);
204 
212 static Vector SetInitialPosition (Ptr<ConstantVelocityMobilityModel> model, std::string coord, double coordVal);
213 
222 static Vector SetSchedPosition (Ptr<ConstantVelocityMobilityModel> model, double at, std::string coord, double coordVal);
223 
224 
226  : m_filename (filename)
227 {
228  std::ifstream file (m_filename.c_str (), std::ios::in);
229  if (!(file.is_open ())) NS_FATAL_ERROR("Could not open trace file " << m_filename.c_str() << " for reading, aborting here \n");
230 }
231 
233 Ns2MobilityHelper::GetMobilityModel (std::string idString, const ObjectStore &store) const
234 {
235  std::istringstream iss;
236  iss.str (idString);
237  uint32_t id (0);
238  iss >> id;
239  Ptr<Object> object = store.Get (id);
240  if (object == 0)
241  {
242  return 0;
243  }
245  if (model == 0)
246  {
247  model = CreateObject<ConstantVelocityMobilityModel> ();
248  object->AggregateObject (model);
249  }
250  return model;
251 }
252 
253 
254 void
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.c_str (), 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 << "\n");
298  continue;
299  }
300 
301  // get mobility model of node
303 
304  // if model not exists, continue
305  if (model == 0)
306  {
307  NS_LOG_ERROR ("Unknown node ID (corrupted file?): " << nodeId << "\n");
308  continue;
309  }
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 " << iNodeId << " " << nodeId <<
325  " position = " << last_pos[iNodeId].m_finalPosition);
326  }
327  }
328  file.close ();
329  }
330 
331  //*****************************************************************
332  // Parse the file a second time to get the rest of its values
333  //*****************************************************************
334 
335  // The reason the file is parsed again is to make this helper robust
336  // to handle trace files with the initial node positions at the end.
337  file.open (m_filename.c_str (), std::ios::in);
338  if (file.is_open ())
339  {
340  while (!file.eof () )
341  {
342  int iNodeId = 0;
343  std::string nodeId;
344  std::string line;
345 
346  getline (file, line);
347 
348  // ignore empty lines
349  if (line.empty ())
350  {
351  continue;
352  }
353 
354  ParseResult pr = ParseNs2Line (line); // Parse line and obtain tokens
355 
356  // Check if the line corresponds with one of the three types of line
357  if (pr.tokens.size () != 4 && pr.tokens.size () != 7 && pr.tokens.size () != 8)
358  {
359  NS_LOG_ERROR ("Line has not correct number of parameters (corrupted file?): " << line << "\n");
360  continue;
361  }
362 
363  // Get the node Id
364  nodeId = GetNodeIdString (pr);
365  iNodeId = GetNodeIdInt (pr);
366  if (iNodeId == -1)
367  {
368  NS_LOG_ERROR ("Node number couldn't be obtained (corrupted file?): " << line << "\n");
369  continue;
370  }
371 
372  // get mobility model of node
374 
375  // if model not exists, continue
376  if (model == 0)
377  {
378  NS_LOG_ERROR ("Unknown node ID (corrupted file?): " << nodeId << "\n");
379  continue;
380  }
381 
382 
383  /*
384  * In this case a initial position is being seted
385  * line like $node_(0) set X_ 151.05190721688197
386  */
387  if (IsSetInitialPos (pr))
388  {
389  // This is the second time this file has been parsed,
390  // and the initial node positions were already set the
391  // first time. So, do nothing this time with this line.
392  continue;
393  }
394 
395  else // NOW EVENTS TO BE SCHEDULED
396  {
397 
398  // This is a scheduled event, so time at should be present
399  double at;
400 
401  if (!IsNumber (pr.tokens[2]))
402  {
403  NS_LOG_WARN ("Time is not a number: " << pr.tokens[2]);
404  continue;
405  }
406 
407  at = pr.dvals[2]; // set time at
408 
409  if ( at < 0 )
410  {
411  NS_LOG_WARN ("Time is less than cero: " << at);
412  continue;
413  }
414 
415 
416 
417  /*
418  * In this case a new waypoint is added
419  * line like $ns_ at 1 "$node_(0) setdest 2 3 4"
420  */
421  if (IsSchedMobilityPos (pr))
422  {
423  if (last_pos[iNodeId].m_targetArrivalTime > at)
424  {
425  NS_LOG_LOGIC ("Did not reach a destination! stoptime = " << last_pos[iNodeId].m_targetArrivalTime << ", at = "<< at);
426  double actuallytraveled = at - last_pos[iNodeId].m_travelStartTime;
427  Vector reached = Vector (
428  last_pos[iNodeId].m_startPosition.x + last_pos[iNodeId].m_speed.x * actuallytraveled,
429  last_pos[iNodeId].m_startPosition.y + last_pos[iNodeId].m_speed.y * actuallytraveled,
430  0
431  );
432  NS_LOG_LOGIC ("Final point = " << last_pos[iNodeId].m_finalPosition << ", actually reached = " << reached);
433  last_pos[iNodeId].m_stopEvent.Cancel ();
434  last_pos[iNodeId].m_finalPosition = reached;
435  }
436  // last position time X coord Y coord velocity
437  last_pos[iNodeId] = SetMovement (model, last_pos[iNodeId].m_finalPosition, at, pr.dvals[5], pr.dvals[6], pr.dvals[7]);
438 
439  // Log new position
440  NS_LOG_DEBUG ("Positions after parse for node " << iNodeId << " " << nodeId << " position =" << last_pos[iNodeId].m_finalPosition);
441  }
442 
443 
444  /*
445  * Scheduled set position
446  * line like $ns_ at 4.634906291962 "$node_(0) set X_ 28.675920486450"
447  */
448  else if (IsSchedSetPos (pr))
449  {
450  // time coordinate coord value
451  last_pos[iNodeId].m_finalPosition = SetSchedPosition (model, at, pr.tokens[5], pr.dvals[6]);
452  if (last_pos[iNodeId].m_targetArrivalTime > at)
453  {
454  last_pos[iNodeId].m_stopEvent.Cancel ();
455  }
456  last_pos[iNodeId].m_targetArrivalTime = at;
457  last_pos[iNodeId].m_travelStartTime = at;
458  // Log new position
459  NS_LOG_DEBUG ("Positions after parse for node " << iNodeId << " " << nodeId <<
460  " position =" << last_pos[iNodeId].m_finalPosition);
461  }
462  else
463  {
464  NS_LOG_WARN ("Format Line is not correct: " << line << "\n");
465  }
466  }
467  }
468  file.close ();
469  }
470 }
471 
472 
474 ParseNs2Line (const std::string& str)
475 {
476  ParseResult ret;
477  std::istringstream s;
478  std::string line;
479 
480  // ignore comments (#)
481  size_t pos_sharp = str.find_first_of ('#');
482  if (pos_sharp != std::string::npos)
483  {
484  line = str.substr (0, pos_sharp);
485  }
486  else
487  {
488  line = str;
489  }
490 
491  line = TrimNs2Line (line);
492 
493  // If line hasn't a correct node Id
494  if (!HasNodeIdNumber (line))
495  {
496  NS_LOG_WARN ("Line has no node Id: " << line);
497  return ret;
498  }
499 
500  s.str (line);
501 
502  while (!s.eof ())
503  {
504  std::string x;
505  s >> x;
506  if (x.length () == 0)
507  {
508  continue;
509  }
510  ret.tokens.push_back (x);
511  int ii (0);
512  double d (0);
513  if (HasNodeIdNumber (x))
514  {
515  x = GetNodeIdFromToken (x);
516  }
517  ret.has_ival.push_back (IsVal<int> (x, ii));
518  ret.ivals.push_back (ii);
519  ret.has_dval.push_back (IsVal<double> (x, d));
520  ret.dvals.push_back (d);
521  ret.svals.push_back (x);
522  }
523 
524  size_t tokensLength = ret.tokens.size (); // number of tokens in line
525  size_t lasTokenLength = ret.tokens[tokensLength - 1].size (); // length of the last token
526 
527  // if it is a scheduled set _[XYZ] or a setdest I need to remove the last "
528  // and re-calculate values
529  if ( (tokensLength == 7 || tokensLength == 8)
530  && (ret.tokens[tokensLength - 1][lasTokenLength - 1] == '"') )
531  {
532 
533  // removes " from the last position
534  ret.tokens[tokensLength - 1] = ret.tokens[tokensLength - 1].substr (0,lasTokenLength - 1);
535 
536  std::string x;
537  x = ret.tokens[tokensLength - 1];
538 
539  if (HasNodeIdNumber (x))
540  {
541  x = GetNodeIdFromToken (x);
542  }
543 
544  // Re calculate values
545  int ii (0);
546  double d (0);
547  ret.has_ival[tokensLength - 1] = IsVal<int> (x, ii);
548  ret.ivals[tokensLength - 1] = ii;
549  ret.has_dval[tokensLength - 1] = IsVal<double> (x, d);
550  ret.dvals[tokensLength - 1] = d;
551  ret.svals[tokensLength - 1] = x;
552 
553  }
554  else if ( (tokensLength == 9 && ret.tokens[tokensLength - 1] == "\"")
555  || (tokensLength == 8 && ret.tokens[tokensLength - 1] == "\""))
556  {
557  // if the line has the " character in this way: $ns_ at 1 "$node_(0) setdest 2 2 1 "
558  // or in this: $ns_ at 4 "$node_(0) set X_ 2 " we need to ignore this last token
559 
560  ret.tokens.erase (ret.tokens.begin () + tokensLength - 1);
561  ret.has_ival.erase (ret.has_ival.begin () + tokensLength - 1);
562  ret.ivals.erase (ret.ivals.begin () + tokensLength - 1);
563  ret.has_dval.erase (ret.has_dval.begin () + tokensLength - 1);
564  ret.dvals.erase (ret.dvals.begin () + tokensLength - 1);
565  ret.svals.erase (ret.svals.begin () + tokensLength - 1);
566 
567  }
568 
569 
570 
571  return ret;
572 }
573 
574 
575 std::string
576 TrimNs2Line (const std::string& s)
577 {
578  std::string ret = s;
579 
580  while (ret.size () > 0 && isblank (ret[0]))
581  {
582  ret.erase (0, 1); // Removes blank spaces at the beginning of the line
583  }
584 
585  while (ret.size () > 0 && (isblank (ret[ret.size () - 1]) || (ret[ret.size () - 1] == ';')))
586  {
587  ret.erase (ret.size () - 1, 1); // Removes blank spaces from at end of line
588  }
589 
590  return ret;
591 }
592 
593 
594 bool
595 IsNumber (const std::string& s)
596 {
597  char *endp;
598  double v = strtod (s.c_str (), &endp); // declared with warn_unused_result
599  NS_UNUSED (v); // suppress "set but not used" compiler warning
600  return endp == s.c_str () + s.size ();
601 }
602 
603 
604 template<class T>
605 bool IsVal (const std::string& str, T& ret)
606 {
607  if (str.size () == 0)
608  {
609  return false;
610  }
611  else if (IsNumber (str))
612  {
613  std::string s2 = str;
614  std::istringstream s (s2);
615  s >> ret;
616  return true;
617  }
618  else
619  {
620  return false;
621  }
622 }
623 
624 
625 bool
626 HasNodeIdNumber (std::string str)
627 {
628 
629  // find brackets
630  std::string::size_type startNodeId = str.find_first_of ("("); // index of left bracket
631  std::string::size_type endNodeId = str.find_first_of (")"); // index of right bracket
632 
633  // Get de nodeId in a string and in a int value
634  std::string nodeId; // node id
635 
636  // if no brackets, continue!
637  if (startNodeId == std::string::npos || endNodeId == std::string::npos)
638  {
639  return false;
640  }
641 
642  nodeId = str.substr (startNodeId + 1, endNodeId - (startNodeId + 1)); // set node id
643 
644  // is number is integer is not negative
645  if (IsNumber (nodeId) && (nodeId.find_first_of (".") == std::string::npos) && (nodeId[0] != '-'))
646  {
647  return true;
648  }
649  else
650  {
651  return false;
652  }
653 }
654 
655 
656 std::string
657 GetNodeIdFromToken (std::string str)
658 {
659  if (HasNodeIdNumber (str))
660  {
661  // find brackets
662  std::string::size_type startNodeId = str.find_first_of ("("); // index of left bracket
663  std::string::size_type endNodeId = str.find_first_of (")"); // index of right bracket
664 
665  return str.substr (startNodeId + 1, endNodeId - (startNodeId + 1)); // set node id
666  }
667  else
668  {
669  return "";
670  }
671 }
672 
673 
674 int
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
696 std::string
698 {
699  switch (pr.tokens.size ())
700  {
701  case 4: // line like $node_(0) set X_ 11
702  return pr.svals[0];
703  break;
704  case 7: // line like $ns_ at 4 "$node_(0) set X_ 28"
705  return pr.svals[3];
706  break;
707  case 8: // line like $ns_ at 1 "$node_(0) setdest 2 3 4"
708  return pr.svals[3];
709  break;
710  default:
711  return "";
712  }
713 }
714 
715 
716 Vector
717 SetOneInitialCoord (Vector position, std::string& coord, double value)
718 {
719 
720  // set the position for the coord.
721  if (coord == NS2_X_COORD)
722  {
723  position.x = value;
724  NS_LOG_DEBUG ("X=" << value);
725  }
726  else if (coord == NS2_Y_COORD)
727  {
728  position.y = value;
729  NS_LOG_DEBUG ("Y=" << value);
730  }
731  else if (coord == NS2_Z_COORD)
732  {
733  position.z = value;
734  NS_LOG_DEBUG ("Z=" << value);
735  }
736  return position;
737 }
738 
739 
740 bool
742 {
743  // number of tokens has $node_( ? has "set" has doble for position?
744  return pr.tokens.size () == 4 && HasNodeIdNumber (pr.tokens[0]) && pr.tokens[1] == NS2_SET && pr.has_dval[3]
745  // coord name is X_, Y_ or Z_ ?
746  && (pr.tokens[2] == NS2_X_COORD || pr.tokens[2] == NS2_Y_COORD || pr.tokens[2] == NS2_Z_COORD);
747 
748 }
749 
750 
751 bool
753 {
754  // correct number of tokens, has $ns_ and at
755  return pr.tokens.size () == 7 && pr.tokens[0] == NS2_NS_SCH && pr.tokens[1] == NS2_AT
756  && pr.tokens[4] == NS2_SET && pr.has_dval[2] && pr.has_dval[3] // has set and double value for time and nodeid
757  && ( pr.tokens[5] == NS2_X_COORD || pr.tokens[5] == NS2_Y_COORD || pr.tokens[5] == NS2_Z_COORD) // has X_, Y_ or Z_?
758  && pr.has_dval[2]; // time is a number
759 }
760 
761 bool
763 {
764  // number of tokens and has $ns_ and has at
765  return pr.tokens.size () == 8 && pr.tokens[0] == NS2_NS_SCH && pr.tokens[1] == NS2_AT
766  // time x coord y coord velocity are numbers?
767  && pr.has_dval[2] && pr.has_dval[5] && pr.has_dval[6] && pr.has_dval[7]
768  && pr.tokens[4] == NS2_SETDEST; // and has setdest
769 
770 }
771 
772 DestinationPoint
773 SetMovement (Ptr<ConstantVelocityMobilityModel> model, Vector last_pos, double at,
774  double xFinalPosition, double yFinalPosition, double speed)
775 {
776  DestinationPoint retval;
777  retval.m_startPosition = last_pos;
778  retval.m_finalPosition = last_pos;
779  retval.m_travelStartTime = at;
780  retval.m_targetArrivalTime = at;
781 
782  if (speed == 0)
783  {
784  // We have to maintain last position, and stop the movement
786  Vector (0, 0, 0));
787  return retval;
788  }
789  if (speed > 0)
790  {
791  // first calculate the time; time = distance / speed
792  double time = std::sqrt (std::pow (xFinalPosition - retval.m_finalPosition.x, 2) + std::pow (yFinalPosition - retval.m_finalPosition.y, 2)) / speed;
793  NS_LOG_DEBUG ("at=" << at << " time=" << time);
794  if (time == 0)
795  {
796  return retval;
797  }
798  // now calculate the xSpeed = distance / time
799  double xSpeed = (xFinalPosition - retval.m_finalPosition.x) / time;
800  double ySpeed = (yFinalPosition - retval.m_finalPosition.y) / time; // & same with ySpeed
801  retval.m_speed = Vector (xSpeed, ySpeed, 0);
802 
803  // quick and dirty set zSpeed = 0
804  double zSpeed = 0;
805 
806  NS_LOG_DEBUG ("Calculated Speed: X=" << xSpeed << " Y=" << ySpeed << " Z=" << zSpeed);
807 
808  // Set the Values
809  Simulator::Schedule (Seconds (at), &ConstantVelocityMobilityModel::SetVelocity, model, Vector (xSpeed, ySpeed, zSpeed));
810  retval.m_stopEvent = Simulator::Schedule (Seconds (at + time), &ConstantVelocityMobilityModel::SetVelocity, model, Vector (0, 0, 0));
811  retval.m_finalPosition.x += xSpeed * time;
812  retval.m_finalPosition.y += ySpeed * time;
813  retval.m_targetArrivalTime += time;
814  }
815  return retval;
816 }
817 
818 
819 Vector
820 SetInitialPosition (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
833 Vector
834 SetSchedPosition (Ptr<ConstantVelocityMobilityModel> model, double at, std::string coord, 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  // Chedule next positions
846 
847  return position;
848 }
849 
850 void
852 {
854 }
855 
856 } // namespace ns3
std::vector< bool > has_dval
points if a tokens has a double value
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
std::vector< bool > has_ival
points if a tokens has an int value
static Vector SetOneInitialCoord(Vector actPos, std::string &coord, double value)
Add one coord to a vector position.
std::string m_filename
filename of file containing ns-2 mobility trace
#define NS2_SETDEST
#define NS2_NS_SCH
void Install(void) const
Read the ns2 trace file and configure the movement patterns of all nodes contained in the global ns3:...
static Vector SetInitialPosition(Ptr< ConstantVelocityMobilityModel > model, std::string coord, double coordVal)
Set initial position for a node.
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.
#define NS2_AT
static bool HasNodeIdNumber(std::string str)
Checks if the value between brackets is a correct nodeId number.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_UNUSED(x)
Mark a local variable as unused.
Definition: unused.h:36
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS2_SET
Vector m_speed
Speed of the last movement (needed to derive reached destination at next schedule = start + velocity ...
std::vector< std::string > tokens
tokens from a line
#define NS2_Z_COORD
void ConfigNodesMovements(const ObjectStore &store) const
Parses ns-2 mobility file to create ns-3 mobility events.
static bool IsSetInitialPos(ParseResult pr)
Check if this corresponds to a line like this: $node_(0) set X_ 123.
double m_travelStartTime
Travel start time is needed to calculate actually traveled time.
static Iterator End(void)
Definition: node-list.cc:235
static std::string GetNodeIdFromToken(std::string str)
Gets nodeId number in string format from the string like $node_(4)
static DestinationPoint SetMovement(Ptr< ConstantVelocityMobilityModel > model, Vector lastPos, double at, double xFinalPosition, double yFinalPosition, double speed)
Set waypoints and speed for movement.
#define NS2_Y_COORD
std::vector< std::string > svals
string value for each token
virtual Ptr< Object > Get(uint32_t i) const =0
Return ith object in store.
static ParseResult ParseNs2Line(const std::string &str)
Parses a line of ns2 mobility.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#define NS2_X_COORD
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static std::string GetNodeIdString(ParseResult pr)
Get node id number in string format
Vector m_startPosition
Start position of last movement.
std::vector< double > dvals
double values for each tokens
Keeps last movement schedule.
Ns2MobilityHelper(std::string filename)
static Vector SetSchedPosition(Ptr< ConstantVelocityMobilityModel > model, double at, std::string coord, double coordVal)
Schedule a set of position for a node.
void SetPosition(const Vector &position)
std::vector< int > ivals
int values for each tokens
Vector GetPosition(void) const
An identifier for simulation events.
Definition: event-id.h:53
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
static Iterator Begin(void)
Definition: node-list.cc:229
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
Mobility model for which the current speed does not change once it has been set and until it is set a...
static std::string TrimNs2Line(const std::string &str)
Put out blank spaces at the start and end of a line.
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:257
EventId m_stopEvent
Event scheduling node&#39;s stop.
Ptr< ConstantVelocityMobilityModel > GetMobilityModel(std::string idString, const ObjectStore &store) const
Get or create a ConstantVelocityMobilityModel corresponding to idString.
Type to maintain line parsed and its values.
static bool IsSchedMobilityPos(ParseResult pr)
Check if this corresponds to a line like this: $ns_ at 1 "$node_(0) set X_ 2".
a class to hold input objects internally
static bool IsVal(const std::string &str, T &ret)
Check if s string represents a numeric value.
double m_targetArrivalTime
When a station arrives to a destination.
Vector m_finalPosition
Final destination to be reached before next schedule.
static bool IsNumber(const std::string &s)
Checks if a string represents a number or it has others characters than digits and point...