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