45 #include "ns3/unused.h"
46 #include "ns3/simulator.h"
47 #include "ns3/node-list.h"
49 #include "ns3/constant-velocity-mobility-model.h"
50 #include "ns2-mobility-helper.h"
58 #define NS2_X_COORD "X_"
59 #define NS2_Y_COORD "Y_"
60 #define NS2_Z_COORD "Z_"
61 #define NS2_SETDEST "setdest"
63 #define NS2_NODEID "$node_("
64 #define NS2_NS_SCH "$ns_"
70 std::vector<std::string> tokens;
71 std::vector<int> ivals;
72 std::vector<bool> has_ival;
73 std::vector<double> dvals;
74 std::vector<bool> has_dval;
75 std::vector<std::string> svals;
90 double m_travelStartTime;
91 double m_targetArrivalTime;
93 m_startPosition (
Vector (0,0,0)),
95 m_finalPosition (
Vector (0,0,0)),
96 m_travelStartTime (0),
97 m_targetArrivalTime (0)
103 static ParseResult ParseNs2Line (
const std::string& str);
106 static std::string TrimNs2Line (
const std::string& str);
109 static bool IsNumber (
const std::string& s);
113 static bool IsVal (
const std::string& str, T& ret);
116 static bool HasNodeIdNumber (std::string str);
119 static std::string GetNodeIdFromToken (std::string str);
125 static std::string GetNodeIdString (
ParseResult pr);
128 static Vector SetOneInitialCoord (
Vector actPos, std::string& coord,
double value);
141 double xFinalPosition,
double yFinalPosition,
double speed);
151 : m_filename (filename)
153 std::ifstream file (m_filename.c_str (), std::ios::in);
154 if (!(file.is_open ()))
NS_FATAL_ERROR(
"Could not open trace file " << m_filename.c_str() <<
" for reading, aborting here \n");
158 Ns2MobilityHelper::GetMobilityModel (std::string idString,
const ObjectStore &store)
const
160 std::istringstream iss;
169 Ptr<ConstantVelocityMobilityModel> model =
object->
GetObject<ConstantVelocityMobilityModel> ();
172 model = CreateObject<ConstantVelocityMobilityModel> ();
173 object->AggregateObject (model);
180 Ns2MobilityHelper::ConfigNodesMovements (
const ObjectStore &store)
const
182 std::map<int, DestinationPoint> last_pos;
191 std::ifstream file (m_filename.c_str (), std::ios::in);
194 while (!file.eof () )
200 getline (file, line);
208 ParseResult pr = ParseNs2Line (line);
212 if (pr.tokens.size () != 4)
218 nodeId = GetNodeIdString (pr);
219 iNodeId = GetNodeIdInt (pr);
222 NS_LOG_ERROR (
"Node number couldn't be obtained (corrupted file?): " << line <<
"\n");
227 Ptr<ConstantVelocityMobilityModel> model = GetMobilityModel (nodeId,store);
232 NS_LOG_ERROR (
"Unknown node ID (corrupted file?): " << nodeId <<
"\n");
241 if (IsSetInitialPos (pr))
243 DestinationPoint point;
245 point.m_finalPosition = SetInitialPosition (model, pr.tokens[2], pr.dvals[3]);
246 last_pos[iNodeId] = point;
249 NS_LOG_DEBUG (
"Positions after parse for node " << iNodeId <<
" " << nodeId <<
250 " position = " << last_pos[iNodeId].m_finalPosition);
262 file.open (m_filename.c_str (), std::ios::in);
265 while (!file.eof () )
271 getline (file, line);
279 ParseResult pr = ParseNs2Line (line);
282 if (pr.tokens.size () != 4 && pr.tokens.size () != 7 && pr.tokens.size () != 8)
284 NS_LOG_ERROR (
"Line has not correct number of parameters (corrupted file?): " << line <<
"\n");
289 nodeId = GetNodeIdString (pr);
290 iNodeId = GetNodeIdInt (pr);
293 NS_LOG_ERROR (
"Node number couldn't be obtained (corrupted file?): " << line <<
"\n");
298 Ptr<ConstantVelocityMobilityModel> model = GetMobilityModel (nodeId,store);
303 NS_LOG_ERROR (
"Unknown node ID (corrupted file?): " << nodeId <<
"\n");
312 if (IsSetInitialPos (pr))
326 if (!IsNumber (pr.tokens[2]))
328 NS_LOG_WARN (
"Time is not a number: " << pr.tokens[2]);
346 if (IsSchedMobilityPos (pr))
348 if (last_pos[iNodeId].m_targetArrivalTime > at)
350 NS_LOG_LOGIC (
"Did not reach a destination! stoptime = " << last_pos[iNodeId].m_targetArrivalTime <<
", at = "<< at);
351 double actuallytraveled = at - last_pos[iNodeId].m_travelStartTime;
352 Vector reached = Vector (
353 last_pos[iNodeId].m_startPosition.x + last_pos[iNodeId].m_speed.x * actuallytraveled,
354 last_pos[iNodeId].m_startPosition.y + last_pos[iNodeId].m_speed.y * actuallytraveled,
357 NS_LOG_LOGIC (
"Final point = " << last_pos[iNodeId].m_finalPosition <<
", actually reached = " << reached);
358 last_pos[iNodeId].m_stopEvent.Cancel ();
359 last_pos[iNodeId].m_finalPosition = reached;
362 last_pos[iNodeId] = SetMovement (model, last_pos[iNodeId].m_finalPosition, at, pr.dvals[5], pr.dvals[6], pr.dvals[7]);
365 NS_LOG_DEBUG (
"Positions after parse for node " << iNodeId <<
" " << nodeId <<
" position =" << last_pos[iNodeId].m_finalPosition);
373 else if (IsSchedSetPos (pr))
376 last_pos[iNodeId].m_finalPosition = SetSchedPosition (model, at, pr.tokens[5], pr.dvals[6]);
377 if (last_pos[iNodeId].m_targetArrivalTime > at)
379 last_pos[iNodeId].m_stopEvent.Cancel ();
381 last_pos[iNodeId].m_targetArrivalTime = at;
382 last_pos[iNodeId].m_travelStartTime = at;
384 NS_LOG_DEBUG (
"Positions after parse for node " << iNodeId <<
" " << nodeId <<
385 " position =" << last_pos[iNodeId].m_finalPosition);
389 NS_LOG_WARN (
"Format Line is not correct: " << line <<
"\n");
399 ParseNs2Line (
const std::string& str)
402 std::istringstream s;
406 size_t pos_sharp = str.find_first_of (
'#');
407 if (pos_sharp != std::string::npos)
409 line = str.substr (0, pos_sharp);
416 line = TrimNs2Line (line);
419 if (!HasNodeIdNumber (line))
431 if (x.length () == 0)
435 ret.tokens.push_back (x);
438 if (HasNodeIdNumber (x))
440 x = GetNodeIdFromToken (x);
442 ret.has_ival.push_back (IsVal<int> (x, ii));
443 ret.ivals.push_back (ii);
444 ret.has_dval.push_back (IsVal<double> (x, d));
445 ret.dvals.push_back (d);
446 ret.svals.push_back (x);
449 size_t tokensLength = ret.tokens.size ();
450 size_t lasTokenLength = ret.tokens[tokensLength - 1].size ();
454 if ( (tokensLength == 7 || tokensLength == 8)
455 && (ret.tokens[tokensLength - 1][lasTokenLength - 1] ==
'"') )
459 ret.tokens[tokensLength - 1] = ret.tokens[tokensLength - 1].substr (0,lasTokenLength - 1);
462 x = ret.tokens[tokensLength - 1];
464 if (HasNodeIdNumber (x))
466 x = GetNodeIdFromToken (x);
472 ret.has_ival[tokensLength - 1] = IsVal<int> (x, ii);
473 ret.ivals[tokensLength - 1] = ii;
474 ret.has_dval[tokensLength - 1] = IsVal<double> (x, d);
475 ret.dvals[tokensLength - 1] = d;
476 ret.svals[tokensLength - 1] = x;
479 else if ( (tokensLength == 9 && ret.tokens[tokensLength - 1] ==
"\"")
480 || (tokensLength == 8 && ret.tokens[tokensLength - 1] ==
"\""))
485 ret.tokens.erase (ret.tokens.begin () + tokensLength - 1);
486 ret.has_ival.erase (ret.has_ival.begin () + tokensLength - 1);
487 ret.ivals.erase (ret.ivals.begin () + tokensLength - 1);
488 ret.has_dval.erase (ret.has_dval.begin () + tokensLength - 1);
489 ret.dvals.erase (ret.dvals.begin () + tokensLength - 1);
490 ret.svals.erase (ret.svals.begin () + tokensLength - 1);
501 TrimNs2Line (
const std::string& s)
505 while (ret.size () > 0 && isblank (ret[0]))
510 while (ret.size () > 0 && isblank (ret[ret.size () - 1]))
512 ret.erase (ret.size () - 1, 1);
520 IsNumber (
const std::string& s)
523 double v = strtod (s.c_str (), &endp);
525 return endp == s.c_str () + s.size ();
530 bool IsVal (
const std::string& str, T& ret)
532 if (str.size () == 0)
536 else if (IsNumber (str))
538 std::string s2 = str;
539 std::istringstream s (s2);
551 HasNodeIdNumber (std::string str)
555 std::string::size_type startNodeId = str.find_first_of (
"(");
556 std::string::size_type endNodeId = str.find_first_of (
")");
562 if (startNodeId == std::string::npos || endNodeId == std::string::npos)
567 nodeId = str.substr (startNodeId + 1, endNodeId - (startNodeId + 1));
570 if (IsNumber (nodeId) && (nodeId.find_first_of (
".") == std::string::npos) && (nodeId[0] !=
'-'))
582 GetNodeIdFromToken (std::string str)
584 if (HasNodeIdNumber (str))
587 std::string::size_type startNodeId = str.find_first_of (
"(");
588 std::string::size_type endNodeId = str.find_first_of (
")");
590 return str.substr (startNodeId + 1, endNodeId - (startNodeId + 1));
600 GetNodeIdInt (ParseResult pr)
603 switch (pr.tokens.size ())
606 result = pr.ivals[0];
609 result = pr.ivals[3];
612 result = pr.ivals[3];
622 GetNodeIdString (ParseResult pr)
624 switch (pr.tokens.size ())
642 SetOneInitialCoord (Vector position, std::string& coord,
double value)
646 if (coord == NS2_X_COORD)
651 else if (coord == NS2_Y_COORD)
656 else if (coord == NS2_Z_COORD)
666 IsSetInitialPos (ParseResult pr)
669 return pr.tokens.size () == 4 && HasNodeIdNumber (pr.tokens[0]) && pr.tokens[1] == NS2_SET && pr.has_dval[3]
671 && (pr.tokens[2] == NS2_X_COORD || pr.tokens[2] == NS2_Y_COORD || pr.tokens[2] == NS2_Z_COORD);
677 IsSchedSetPos (ParseResult pr)
680 return pr.tokens.size () == 7 && pr.tokens[0] == NS2_NS_SCH && pr.tokens[1] == NS2_AT
681 && pr.tokens[4] == NS2_SET && pr.has_dval[2] && pr.has_dval[3]
682 && ( pr.tokens[5] == NS2_X_COORD || pr.tokens[5] == NS2_Y_COORD || pr.tokens[5] == NS2_Z_COORD)
687 IsSchedMobilityPos (ParseResult pr)
690 return pr.tokens.size () == 8 && pr.tokens[0] == NS2_NS_SCH && pr.tokens[1] == NS2_AT
692 && pr.has_dval[2] && pr.has_dval[5] && pr.has_dval[6] && pr.has_dval[7]
693 && pr.tokens[4] == NS2_SETDEST;
698 SetMovement (Ptr<ConstantVelocityMobilityModel> model, Vector last_pos,
double at,
699 double xFinalPosition,
double yFinalPosition,
double speed)
701 DestinationPoint retval;
702 retval.m_startPosition = last_pos;
703 retval.m_finalPosition = last_pos;
704 retval.m_travelStartTime = at;
705 retval.m_targetArrivalTime = at;
717 double time = std::sqrt (std::pow (xFinalPosition - retval.m_finalPosition.x, 2) + std::pow (yFinalPosition - retval.m_finalPosition.y, 2)) / speed;
724 double xSpeed = (xFinalPosition - retval.m_finalPosition.x) / time;
725 double ySpeed = (yFinalPosition - retval.m_finalPosition.y) / time;
726 retval.m_speed = Vector (xSpeed, ySpeed, 0);
731 NS_LOG_DEBUG (
"Calculated Speed: X=" << xSpeed <<
" Y=" << ySpeed <<
" Z=" << zSpeed);
736 retval.m_finalPosition.x += xSpeed * time;
737 retval.m_finalPosition.y += ySpeed * time;
738 retval.m_targetArrivalTime += time;
745 SetInitialPosition (Ptr<ConstantVelocityMobilityModel> model, std::string coord,
double coordVal)
747 model->SetPosition (SetOneInitialCoord (model->GetPosition (), coord, coordVal));
750 position.
x = model->GetPosition ().x;
751 position.y = model->GetPosition ().y;
752 position.z = model->GetPosition ().z;
759 SetSchedPosition (Ptr<ConstantVelocityMobilityModel> model,
double at, std::string coord,
double coordVal)
762 model->SetPosition (SetOneInitialCoord (model->GetPosition (), coord, coordVal));
765 position.
x = model->GetPosition ().x;
766 position.y = model->GetPosition ().y;
767 position.z = model->GetPosition ().z;
smart pointer class similar to boost::intrusive_ptr
#define NS_LOG_COMPONENT_DEFINE(name)
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
#define NS_FATAL_ERROR(msg)
fatal error handling
static Iterator End(void)
#define NS_LOG_LOGIC(msg)
Keeps last movement schedule. If new movement occurs during a current one, node stopping must be canc...
Ns2MobilityHelper(std::string filename)
void SetPosition(const Vector &position)
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
an identifier for simulation events.
static Iterator Begin(void)
#define NS_LOG_DEBUG(msg)
#define NS_LOG_ERROR(msg)
Ptr< T > GetObject(void) const
void SetVelocity(const Vector &speed)