A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
waypoint-mobility-model.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 Phillip Sitbon
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: Phillip Sitbon <phillip@sitbon.net>
19  */
20 #include <limits>
21 #include "ns3/abort.h"
22 #include "ns3/simulator.h"
23 #include "ns3/uinteger.h"
24 #include "ns3/log.h"
25 #include "ns3/boolean.h"
26 #include "waypoint-mobility-model.h"
27 #include "ns3/config.h"
28 #include "ns3/test.h"
29 
30 NS_LOG_COMPONENT_DEFINE ("WaypointMobilityModel");
31 
32 namespace ns3 {
33 
34 NS_OBJECT_ENSURE_REGISTERED (WaypointMobilityModel);
35 
36 
37 TypeId
38 WaypointMobilityModel::GetTypeId (void)
39 {
40  static TypeId tid = TypeId ("ns3::WaypointMobilityModel")
41  .SetParent<MobilityModel> ()
42  .SetGroupName ("Mobility")
43  .AddConstructor<WaypointMobilityModel> ()
44  .AddAttribute ("NextWaypoint", "The next waypoint used to determine position.",
46  WaypointValue (),
47  MakeWaypointAccessor (&WaypointMobilityModel::GetNextWaypoint),
48  MakeWaypointChecker ())
49  .AddAttribute ("WaypointsLeft", "The number of waypoints remaining.",
51  UintegerValue (0),
52  MakeUintegerAccessor (&WaypointMobilityModel::WaypointsLeft),
53  MakeUintegerChecker<uint32_t> ())
54  .AddAttribute ("LazyNotify", "Only call NotifyCourseChange when position is calculated.",
55  BooleanValue (false),
56  MakeBooleanAccessor (&WaypointMobilityModel::m_lazyNotify),
57  MakeBooleanChecker ())
58  .AddAttribute ("InitialPositionIsWaypoint", "Calling SetPosition with no waypoints creates a waypoint.",
59  BooleanValue (false),
60  MakeBooleanAccessor (&WaypointMobilityModel::m_initialPositionIsWaypoint),
61  MakeBooleanChecker ())
62  ;
63  return tid;
64 }
65 
66 
68  : m_first (true),
69  m_lazyNotify (false),
70  m_initialPositionIsWaypoint (false)
71 {
72 }
73 WaypointMobilityModel::~WaypointMobilityModel ()
74 {
75 }
76 void
78 {
80 }
81 void
83 {
84  if ( m_first )
85  {
86  m_first = false;
87  m_current = m_next = waypoint;
88  }
89  else
90  {
91  NS_ABORT_MSG_IF ( !m_waypoints.empty () && (m_waypoints.back ().time >= waypoint.time),
92  "Waypoints must be added in ascending time order");
93  m_waypoints.push_back (waypoint);
94  }
95 
96  if ( !m_lazyNotify )
97  {
98  Simulator::Schedule (waypoint.time, &WaypointMobilityModel::Update, this);
99  }
100 }
101 Waypoint
103 {
104  Update ();
105  return m_next;
106 }
107 uint32_t
109 {
110  Update ();
111  return m_waypoints.size ();
112 }
113 void
114 WaypointMobilityModel::Update (void) const
115 {
116  const Time now = Simulator::Now ();
117  bool newWaypoint = false;
118 
119  if ( now < m_current.time )
120  {
121  return;
122  }
123 
124  while ( now >= m_next.time )
125  {
126  if ( m_waypoints.empty () )
127  {
128  if ( m_current.time <= m_next.time )
129  {
130  /*
131  Set m_next.time = -1 to make sure this doesn't happen more than once.
132  The comparison here still needs to be '<=' in the case of mobility with one waypoint.
133  */
134  m_next.time = Seconds (-1.0);
135  m_current.position = m_next.position;
136  m_current.time = now;
137  m_velocity = Vector (0,0,0);
139  }
140  else
141  {
142  m_current.time = now;
143  }
144 
145  return;
146  }
147 
148  m_current = m_next;
149  m_next = m_waypoints.front ();
150  m_waypoints.pop_front ();
151  newWaypoint = true;
152 
153  const double t_span = (m_next.time - m_current.time).GetSeconds ();
154  NS_ASSERT (t_span > 0);
155  m_velocity.x = (m_next.position.x - m_current.position.x) / t_span;
156  m_velocity.y = (m_next.position.y - m_current.position.y) / t_span;
157  m_velocity.z = (m_next.position.z - m_current.position.z) / t_span;
158  }
159 
160  if ( now > m_current.time ) // Won't ever be less, but may be equal
161  {
162  const double t_diff = (now - m_current.time).GetSeconds ();
163  m_current.position.x += m_velocity.x * t_diff;
164  m_current.position.y += m_velocity.y * t_diff;
165  m_current.position.z += m_velocity.z * t_diff;
166  m_current.time = now;
167  }
168 
169  if ( newWaypoint )
170  {
172  }
173 }
174 Vector
176 {
177  Update ();
178  return m_current.position;
179 }
180 void
182 {
183  const Time now = Simulator::Now ();
184 
185  if ( m_first && m_initialPositionIsWaypoint )
186  {
187  AddWaypoint (Waypoint (now, position));
188  return;
189  }
190 
191  Update ();
192  m_current.time = std::max (now, m_next.time);
193  m_current.position = position;
194  m_velocity = Vector (0,0,0);
195 
196  if ( !m_first && (now >= m_current.time) )
197  {
198  // This is only a course change if the node is actually moving
200  }
201 }
202 void
204 {
205  m_waypoints.clear ();
206  m_current.time = Time(std::numeric_limits<uint64_t>::infinity());
207  m_next.time = m_current.time;
208  m_first = true;
209 }
210 Vector
212 {
213  return m_velocity;
214 }
215 
216 } // namespace ns3
217 
virtual Vector DoGetVelocity(void) const
double x
Definition: vector.h:49
keep track of time unit.
Definition: nstime.h:149
void AddWaypoint(const Waypoint &waypoint)
#define NS_ASSERT(condition)
Definition: assert.h:64
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
virtual Vector DoGetPosition(void) const
virtual void DoDispose(void)
Definition: object.cc:335
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
a 3d vector
Definition: vector.h:31
virtual void DoSetPosition(const Vector &position)
void NotifyCourseChange(void) const
double y
Definition: vector.h:53
static Time Now(void)
Definition: simulator.cc:179
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if cond is true.
Definition: abort.h:98
Waypoint GetNextWaypoint(void) const
a (time, location) pair.
Definition: waypoint.h:34
double z
Definition: vector.h:57