A Discrete-Event Network Simulator
API
steady-state-random-waypoint-mobility-model.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2009 IITP RAS
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: Denis Fakhriev <fakhriev@iitp.ru>
19  */
20 #include <cmath>
21 #include "ns3/simulator.h"
22 #include "ns3/double.h"
24 #include "ns3/test.h"
25 
26 namespace ns3 {
27 
28 NS_OBJECT_ENSURE_REGISTERED (SteadyStateRandomWaypointMobilityModel);
29 
30 TypeId
32 {
33  static TypeId tid = TypeId ("ns3::SteadyStateRandomWaypointMobilityModel")
35  .SetGroupName ("Mobility")
36  .AddConstructor<SteadyStateRandomWaypointMobilityModel> ()
37  .AddAttribute ("MinSpeed",
38  "Minimum speed value, [m/s]",
39  DoubleValue (0.3),
41  MakeDoubleChecker<double> ())
42  .AddAttribute ("MaxSpeed",
43  "Maximum speed value, [m/s]",
44  DoubleValue (0.7),
46  MakeDoubleChecker<double> ())
47  .AddAttribute ("MinPause",
48  "Minimum pause value, [s]",
49  DoubleValue (0.0),
51  MakeDoubleChecker<double> ())
52  .AddAttribute ("MaxPause",
53  "Maximum pause value, [s]",
54  DoubleValue (0.0),
56  MakeDoubleChecker<double> ())
57  .AddAttribute ("MinX",
58  "Minimum X value of traveling region, [m]",
59  DoubleValue (1),
61  MakeDoubleChecker<double> ())
62  .AddAttribute ("MaxX",
63  "Maximum X value of traveling region, [m]",
64  DoubleValue (1),
66  MakeDoubleChecker<double> ())
67  .AddAttribute ("MinY",
68  "Minimum Y value of traveling region, [m]",
69  DoubleValue (1),
71  MakeDoubleChecker<double> ())
72  .AddAttribute ("MaxY",
73  "Maximum Y value of traveling region, [m]",
74  DoubleValue (1),
76  MakeDoubleChecker<double> ())
77  .AddAttribute ("Z",
78  "Z value of traveling region (fixed), [m]",
79  DoubleValue (0.0),
81  MakeDoubleChecker<double> ());
82 
83  return tid;
84 }
85 
87  alreadyStarted (false)
88 {
89  m_speed = CreateObject<UniformRandomVariable> ();
90  m_pause = CreateObject<UniformRandomVariable> ();
91  m_x1_r = CreateObject<UniformRandomVariable> ();
92  m_y1_r = CreateObject<UniformRandomVariable> ();
93  m_x2_r = CreateObject<UniformRandomVariable> ();
94  m_y2_r = CreateObject<UniformRandomVariable> ();
95  m_u_r = CreateObject<UniformRandomVariable> ();
96  m_x = CreateObject<UniformRandomVariable> ();
97  m_y = CreateObject<UniformRandomVariable> ();
98  m_position = CreateObject<RandomBoxPositionAllocator> ();
99 }
100 
101 void
103 {
106 }
107 
108 void
110 {
111  alreadyStarted = true;
112  // Configure random variables based on attributes
113  NS_ASSERT (m_minSpeed >= 1e-6);
117  NS_ASSERT (m_minX < m_maxX);
118  NS_ASSERT (m_minY < m_maxY);
119  m_x->SetAttribute ("Min", DoubleValue (m_minX));
120  m_x->SetAttribute ("Max", DoubleValue (m_maxX));
121  m_y->SetAttribute ("Min", DoubleValue (m_minY));
122  m_y->SetAttribute ("Max", DoubleValue (m_maxY));
123  m_position->SetX (m_x);
124  m_position->SetY (m_y);
125  Ptr<ConstantRandomVariable> z = CreateObject<ConstantRandomVariable> ();
126  z->SetAttribute ("Constant", DoubleValue (m_z));
127  m_position->SetZ (z);
128 
132 
133  m_helper.Update ();
134  m_helper.Pause ();
135 
136  // calculate the steady-state probability that a node is initially paused
137  double expectedPauseTime = (m_minPause + m_maxPause)/2;
138  double a = m_maxX - m_minX;
139  double b = m_maxY - m_minY;
140  double v0 = m_minSpeed;
141  double v1 = m_maxSpeed;
142  double log1 = b*b / a*std::log (std::sqrt ((a*a)/(b*b) + 1) + a/b);
143  double log2 = a*a / b*std::log (std::sqrt ((b*b)/(a*a) + 1) + b/a);
144  double expectedTravelTime = 1.0/6.0*(log1 + log2);
145  expectedTravelTime += 1.0/15.0*((a*a*a)/(b*b) + (b*b*b)/(a*a)) -
146  1.0/15.0*std::sqrt (a*a + b*b)*((a*a)/(b*b) + (b*b)/(a*a) - 3);
147  if (v0 == v1)
148  {
149  expectedTravelTime /= v0;
150  }
151  else
152  {
153  expectedTravelTime *= std::log (v1/v0)/(v1 - v0);
154  }
155  double probabilityPaused = expectedPauseTime/(expectedPauseTime + expectedTravelTime);
156  NS_ASSERT (probabilityPaused >= 0 && probabilityPaused <= 1);
157 
158  double u = m_u_r->GetValue (0, 1);
159  if (u < probabilityPaused) // node initially paused
160  {
161  m_helper.SetPosition (m_position->GetNext ());
162  u = m_u_r->GetValue (0, 1);
163  Time pause;
164  if (m_minPause != m_maxPause)
165  {
166  if (u < (2*m_minPause/(m_minPause + m_maxPause)))
167  {
168  pause = Seconds (u*(m_minPause + m_maxPause)/2);
169  }
170  else
171  {
172  // there is an error in equation 20 in the Tech. Report MCS-03-04
173  // this error is corrected in the TMC 2004 paper and below
174  pause = Seconds (m_maxPause - std::sqrt ((1 - u)*(m_maxPause*m_maxPause - m_minPause*m_minPause)));
175  }
176  }
177  else // if pause is constant
178  {
179  pause = Seconds (u*expectedPauseTime);
180  }
183  }
184  else // node initially moving
185  {
186  double x1, x2, y1, y2;
187  x1 = x2 = y1 = y2 = 0;
188  double r = 0;
189  double u1 = 1;
190  while (u1 >= r)
191  {
192  x1 = m_x1_r->GetValue (0, a);
193  y1 = m_y1_r->GetValue (0, b);
194  x2 = m_x2_r->GetValue (0, a);
195  y2 = m_y2_r->GetValue (0, b);
196  u1 = m_u_r->GetValue (0, 1);
197  r = std::sqrt (((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1))/(a*a + b*b));
198  NS_ASSERT (r <= 1);
199  }
200  double u2 = m_u_r->GetValue (0, 1);
201  m_helper.SetPosition (Vector (m_minX + u2*x1 + (1 - u2)*x2, m_minY + u2*y1 + (1 - u2)*y2, m_z));
204  Vector (m_minX + x2, m_minY + y2, m_z));
205  }
207 }
208 
209 void
211 {
212  m_helper.Update ();
213  Vector m_current = m_helper.GetCurrentPosition ();
214  NS_ASSERT (m_minX <= m_current.x && m_current.x <= m_maxX);
215  NS_ASSERT (m_minY <= m_current.y && m_current.y <= m_maxY);
216  NS_ASSERT (m_minX <= destination.x && destination.x <= m_maxX);
217  NS_ASSERT (m_minY <= destination.y && destination.y <= m_maxY);
218  double u = m_u_r->GetValue (0, 1);
219  double speed = std::pow (m_maxSpeed, u)/std::pow (m_minSpeed, u - 1);
220  double dx = (destination.x - m_current.x);
221  double dy = (destination.y - m_current.y);
222  double dz = (destination.z - m_current.z);
223  double k = speed / std::sqrt (dx*dx + dy*dy + dz*dz);
224 
225  m_helper.SetVelocity (Vector (k*dx, k*dy, k*dz));
226  m_helper.Unpause ();
227  Time travelDelay = Seconds (CalculateDistance (destination, m_current) / speed);
228  m_event = Simulator::Schedule (travelDelay,
231 }
232 
233 void
235 {
236  m_helper.Update ();
237  Vector m_current = m_helper.GetCurrentPosition ();
238  NS_ASSERT (m_minX <= m_current.x && m_current.x <= m_maxX);
239  NS_ASSERT (m_minY <= m_current.y && m_current.y <= m_maxY);
240  Vector destination = m_position->GetNext ();
241  double speed = m_speed->GetValue ();
242  double dx = (destination.x - m_current.x);
243  double dy = (destination.y - m_current.y);
244  double dz = (destination.z - m_current.z);
245  double k = speed / std::sqrt (dx*dx + dy*dy + dz*dz);
246 
247  m_helper.SetVelocity (Vector (k*dx, k*dy, k*dz));
248  m_helper.Unpause ();
249  Time travelDelay = Seconds (CalculateDistance (destination, m_current) / speed);
250  m_event = Simulator::Schedule (travelDelay,
253 }
254 
255 void
257 {
258  m_helper.Update ();
259  m_helper.Pause ();
260  Time pause = Seconds (m_pause->GetValue ());
263 }
264 
265 Vector
267 {
268  m_helper.Update ();
269  return m_helper.GetCurrentPosition ();
270 }
271 void
273 {
274  if (alreadyStarted)
275  {
276  m_helper.SetPosition (position);
277  m_event.Cancel ();
279  }
280 }
281 Vector
283 {
284  return m_helper.GetVelocity ();
285 }
286 int64_t
288 {
289  int64_t positionStreamsAllocated = 0;
290  m_speed->SetStream (stream);
291  m_pause->SetStream (stream + 1);
292  m_x1_r->SetStream (stream + 2);
293  m_y1_r->SetStream (stream + 3);
294  m_x2_r->SetStream (stream + 4);
295  m_y2_r->SetStream (stream + 5);
296  m_u_r->SetStream (stream + 6);
297  m_x->SetStream (stream + 7);
298  m_y->SetStream (stream + 8);
299  positionStreamsAllocated = m_position->AssignStreams (stream + 9);
300  return (9 + positionStreamsAllocated);
301 }
302 
303 } // namespace ns3
void Unpause(void)
Resume mobility from current position at current velocity.
Vector GetVelocity(void) const
Get velocity; if paused, will return a zero vector.
void SetPosition(const Vector &position)
Set position vector.
void Pause(void)
Pause mobility at current position.
void SetVelocity(const Vector &vel)
Set new velocity vector.
void Update(void) const
Update position, if not paused, from last position and time of last update.
Vector GetCurrentPosition(void) const
Get current position vector.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:41
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:71
void Cancel(void)
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:53
Keep track of the current position and velocity of an object.
void NotifyCourseChange(void) const
Must be invoked by subclasses when the course of the position changes to notify course change listene...
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:256
virtual void DoInitialize(void)
Initialize() implementation.
Definition: object.cc:353
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:587
Ptr< UniformRandomVariable > m_u_r
rv used in step 5 of algorithm
static TypeId GetTypeId(void)
Register this type with the TypeId system.
Ptr< UniformRandomVariable > m_y2_r
rv used in rejection sampling phase
Ptr< UniformRandomVariable > m_pause
random variable for pause values
Ptr< UniformRandomVariable > m_x2_r
rv used in rejection sampling phase
void SteadyStateBeginWalk(const Vector &destination)
Use provided destination to calculate travel delay, and schedule a Start() event at that time.
Ptr< UniformRandomVariable > m_y
rv used for position allocator
void DoInitializePrivate(void)
Configure random variables based on attributes; calculate the steady state probability that node is i...
Ptr< UniformRandomVariable > m_speed
random variable for speed values
void BeginWalk(void)
Start a motion period and schedule the ending of the motion.
Ptr< UniformRandomVariable > m_x1_r
rv used in rejection sampling phase
Ptr< UniformRandomVariable > m_x
rv used for position allocator
ConstantVelocityHelper m_helper
helper for velocity computations
Ptr< UniformRandomVariable > m_y1_r
rv used in rejection sampling phase
virtual int64_t DoAssignStreams(int64_t)
The default implementation does nothing but return the passed-in parameter.
Ptr< RandomBoxPositionAllocator > m_position
position allocator
void Start(void)
Start a pause period and schedule the ending of the pause.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: double.h:42
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double CalculateDistance(const Vector3D &a, const Vector3D &b)
Definition: vector.cc:105