A Discrete-Event Network Simulator
API
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 
51 namespace ns3
52 {
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 
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 };
78 
87 {
88  Vector m_startPosition;
89  Vector m_speed;
91  Vector m_finalPosition;
97  : m_startPosition(Vector(0, 0, 0)),
98  m_speed(Vector(0, 0, 0)),
99  m_finalPosition(Vector(0, 0, 0)),
101  m_targetArrivalTime(0){};
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,
203  Vector lastPos,
204  double at,
205  double xFinalPosition,
206  double yFinalPosition,
207  double speed);
208 
216 static Vector SetInitialPosition(Ptr<ConstantVelocityMobilityModel> model,
217  std::string coord,
218  double coordVal);
219 
228 static 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 
245 Ns2MobilityHelper::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 
265 void
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 
494 ParseNs2Line(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  {
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  {
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 
589 std::string
590 TrimNs2Line(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 
607 bool
608 IsNumber(const std::string& s)
609 {
610  char* endp;
611  strtod(s.c_str(), &endp);
612  return endp == s.c_str() + s.size();
613 }
614 
615 template <class T>
616 bool
617 IsVal(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 
635 bool
636 HasNodeIdNumber(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 
657 std::string
658 GetNodeIdFromToken(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 
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  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 
712 Vector
713 SetOneInitialCoord(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 
734 bool
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 
746 bool
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 
758 bool
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 
769 DestinationPoint
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 
829 Vector
830 SetInitialPosition(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
843 Vector
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 
863 void
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:1326
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