A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
steady-state-random-waypoint-mobility-model.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2009 IITP RAS
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Denis Fakhriev <fakhriev@iitp.ru>
7 */
9
10#include "ns3/double.h"
11#include "ns3/event-id.h"
12#include "ns3/simulator.h"
13#include "ns3/test.h"
14
15#include <cmath>
16
17namespace ns3
18{
19
21
24{
25 static TypeId tid =
26 TypeId("ns3::SteadyStateRandomWaypointMobilityModel")
28 .SetGroupName("Mobility")
30 .AddAttribute("MinSpeed",
31 "Minimum speed value, [m/s]",
32 DoubleValue(0.3),
35 .AddAttribute("MaxSpeed",
36 "Maximum speed value, [m/s]",
37 DoubleValue(0.7),
40 .AddAttribute("MinPause",
41 "Minimum pause value, [s]",
42 DoubleValue(0.0),
45 .AddAttribute("MaxPause",
46 "Maximum pause value, [s]",
47 DoubleValue(0.0),
50 .AddAttribute("MinX",
51 "Minimum X value of traveling region, [m]",
52 DoubleValue(1),
55 .AddAttribute("MaxX",
56 "Maximum X value of traveling region, [m]",
57 DoubleValue(1),
60 .AddAttribute("MinY",
61 "Minimum Y value of traveling region, [m]",
62 DoubleValue(1),
65 .AddAttribute("MaxY",
66 "Maximum Y value of traveling region, [m]",
67 DoubleValue(1),
70 .AddAttribute("Z",
71 "Z value of traveling region (fixed), [m]",
72 DoubleValue(0.0),
75
76 return tid;
77}
78
93
98
99void
105
106void
108{
109 alreadyStarted = true;
110 // Configure random variables based on attributes
111 NS_ASSERT(m_minSpeed >= 1e-6);
113 m_speed->SetAttribute("Min", DoubleValue(m_minSpeed));
114 m_speed->SetAttribute("Max", DoubleValue(m_maxSpeed));
117 m_x->SetAttribute("Min", DoubleValue(m_minX));
118 m_x->SetAttribute("Max", DoubleValue(m_maxX));
119 m_y->SetAttribute("Min", DoubleValue(m_minY));
120 m_y->SetAttribute("Max", DoubleValue(m_maxY));
121 m_position->SetX(m_x);
122 m_position->SetY(m_y);
124 z->SetAttribute("Constant", DoubleValue(m_z));
125 m_position->SetZ(z);
126
128 m_pause->SetAttribute("Min", DoubleValue(m_minPause));
129 m_pause->SetAttribute("Max", DoubleValue(m_maxPause));
130
131 m_helper.Update();
132 m_helper.Pause();
133
134 // calculate the steady-state probability that a node is initially paused
135 // See the discussion in MR 2675 and
136 // Mathai, Moschopoulos and Pederzoli, Rendiconti Del Circolo Matematico Di Palermo,
137 // Serie II, Tomo XLVIII (1999), p. 163.
138 // https://www.researchgate.net/publication/250677777_Random_points_associated_with_rectangles
139
140 double expectedPauseTime = (m_minPause + m_maxPause) / 2;
141 double a = m_maxX - m_minX;
142 double b = m_maxY - m_minY;
143 double v0 = m_minSpeed;
144 double v1 = m_maxSpeed;
145 double log1 = b * b / a * std::log(std::sqrt((a * a) / (b * b) + 1) + a / b);
146 double log2 = a * a / b * std::log(std::sqrt((b * b) / (a * a) + 1) + b / a);
147 double expectedTravelTime = 1.0 / 6.0 * (log1 + log2);
148 expectedTravelTime +=
149 1.0 / 15.0 * ((a * a * a) / (b * b) + (b * b * b) / (a * a)) -
150 1.0 / 15.0 * std::hypot(a, b) * ((a * a) / (b * b) + (b * b) / (a * a) - 3);
151 if (v0 == v1)
152 {
153 expectedTravelTime /= v0;
154 }
155 else
156 {
157 expectedTravelTime *= std::log(v1 / v0) / (v1 - v0);
158 }
159 double probabilityPaused = expectedPauseTime / (expectedPauseTime + expectedTravelTime);
160 NS_ASSERT(probabilityPaused >= 0 && probabilityPaused <= 1);
161
162 double u = m_u_r->GetValue(0, 1);
163 if (u < probabilityPaused) // node initially paused
164 {
165 m_helper.SetPosition(m_position->GetNext());
166 u = m_u_r->GetValue(0, 1);
167 Time pause;
168 if (m_minPause != m_maxPause)
169 {
170 if (u < (2 * m_minPause / (m_minPause + m_maxPause)))
171 {
172 pause = Seconds(u * (m_minPause + m_maxPause) / 2);
173 }
174 else
175 {
176 // there is an error in equation 20 in the Tech. Report MCS-03-04
177 // this error is corrected in the TMC 2004 paper and below
178 pause = Seconds(m_maxPause - std::sqrt((1 - u) * (m_maxPause * m_maxPause -
180 }
181 }
182 else // if pause is constant
183 {
184 pause = Seconds(u * expectedPauseTime);
185 }
186 NS_ASSERT(!m_event.IsPending());
187 m_event =
189 }
190 else // node initially moving
191 {
192 double x1;
193 double x2;
194 double y1;
195 double y2;
196 x1 = x2 = y1 = y2 = 0;
197 double r = 0;
198 double u1 = 1;
199 while (u1 >= r)
200 {
201 x1 = m_x1_r->GetValue(0, a);
202 y1 = m_y1_r->GetValue(0, b);
203 x2 = m_x2_r->GetValue(0, a);
204 y2 = m_y2_r->GetValue(0, b);
205 u1 = m_u_r->GetValue(0, 1);
206 r = std::hypot((x2 - x1), (y2 - y1)) / std::hypot(a, b);
207 NS_ASSERT(r <= 1);
208 }
209 double u2 = m_u_r->GetValue(0, 1);
210 m_helper.SetPosition(
211 Vector(m_minX + u2 * x1 + (1 - u2) * x2, m_minY + u2 * y1 + (1 - u2) * y2, m_z));
212 NS_ASSERT(!m_event.IsPending());
213 m_event =
215 this,
216 Vector(m_minX + x2, m_minY + y2, m_z));
217 }
219}
220
221void
223{
224 m_helper.Update();
225 Vector m_current = m_helper.GetCurrentPosition();
226 NS_ASSERT(m_minX <= m_current.x && m_current.x <= m_maxX);
227 NS_ASSERT(m_minY <= m_current.y && m_current.y <= m_maxY);
228 NS_ASSERT(m_minX <= destination.x && destination.x <= m_maxX);
229 NS_ASSERT(m_minY <= destination.y && destination.y <= m_maxY);
230 double u = m_u_r->GetValue(0, 1);
231 double speed = std::pow(m_maxSpeed, u) / std::pow(m_minSpeed, u - 1);
232 Vector deltaPos = destination - m_current;
233 double rate = speed / deltaPos.GetLength();
234 m_helper.SetVelocity(rate * deltaPos);
235 m_helper.Unpause();
236 Time travelDelay = Seconds(CalculateDistance(destination, m_current) / speed);
237 m_event =
240}
241
242void
244{
245 m_helper.Update();
246 Vector m_current = m_helper.GetCurrentPosition();
247 NS_ASSERT(m_minX <= m_current.x && m_current.x <= m_maxX);
248 NS_ASSERT(m_minY <= m_current.y && m_current.y <= m_maxY);
249 Vector destination = m_position->GetNext();
250 double speed = m_speed->GetValue();
251 Vector deltaPos = destination - m_current;
252 double rate = speed / deltaPos.GetLength();
253 m_helper.SetVelocity(rate * deltaPos);
254 m_helper.Unpause();
255 Time travelDelay = Seconds(CalculateDistance(destination, m_current) / speed);
256 m_event =
259}
260
261void
270
271Vector
273{
274 m_helper.Update();
275 return m_helper.GetCurrentPosition();
276}
277
278void
280{
281 if (alreadyStarted)
282 {
283 m_helper.SetPosition(position);
284 m_event.Cancel();
286 }
287}
288
289Vector
291{
292 return m_helper.GetVelocity();
293}
294
295int64_t
297{
298 int64_t positionStreamsAllocated = 0;
299 m_speed->SetStream(stream);
300 m_pause->SetStream(stream + 1);
301 m_x1_r->SetStream(stream + 2);
302 m_y1_r->SetStream(stream + 3);
303 m_x2_r->SetStream(stream + 4);
304 m_y2_r->SetStream(stream + 5);
305 m_u_r->SetStream(stream + 6);
306 m_x->SetStream(stream + 7);
307 m_y->SetStream(stream + 8);
308 positionStreamsAllocated = m_position->AssignStreams(stream + 9);
309 return (9 + positionStreamsAllocated);
310}
311
312} // namespace ns3
uint32_t r
uint32_t u
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition double.h:31
void NotifyCourseChange() const
Must be invoked by subclasses when the course of the position changes to notify course change listene...
virtual void DoInitialize()
Initialize() implementation.
Definition object.cc:437
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:70
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:580
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:614
Ptr< UniformRandomVariable > m_u_r
rv used in step 5 of algorithm
int64_t DoAssignStreams(int64_t) override
The default implementation does nothing but return the passed-in parameter.
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
Ptr< UniformRandomVariable > m_speed
random variable for speed values
static TypeId GetTypeId()
Register this type with the TypeId system.
Ptr< UniformRandomVariable > m_x1_r
rv used in rejection sampling phase
void DoInitializePrivate()
Configure random variables based on attributes; calculate the steady state probability that node is i...
void BeginWalk()
Start a motion period and schedule the ending of the motion.
void Start()
Start a pause period and schedule the ending of the pause.
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
Ptr< RandomBoxPositionAllocator > m_position
position allocator
Simulation virtual time values and global simulation resolution.
Definition nstime.h:95
a unique identifier for an interface.
Definition type-id.h:50
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:999
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
Ptr< const AttributeChecker > MakeDoubleChecker()
Definition double.h:82
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:32
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:627
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1273
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double CalculateDistance(const Vector3D &a, const Vector3D &b)
Definition vector.cc:96