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/simulator.h"
12#include "ns3/test.h"
13
14#include <cmath>
15
16namespace ns3
17{
18
20
23{
24 static TypeId tid =
25 TypeId("ns3::SteadyStateRandomWaypointMobilityModel")
27 .SetGroupName("Mobility")
29 .AddAttribute("MinSpeed",
30 "Minimum speed value, [m/s]",
31 DoubleValue(0.3),
34 .AddAttribute("MaxSpeed",
35 "Maximum speed value, [m/s]",
36 DoubleValue(0.7),
39 .AddAttribute("MinPause",
40 "Minimum pause value, [s]",
41 DoubleValue(0.0),
44 .AddAttribute("MaxPause",
45 "Maximum pause value, [s]",
46 DoubleValue(0.0),
49 .AddAttribute("MinX",
50 "Minimum X value of traveling region, [m]",
51 DoubleValue(1),
54 .AddAttribute("MaxX",
55 "Maximum X value of traveling region, [m]",
56 DoubleValue(1),
59 .AddAttribute("MinY",
60 "Minimum Y value of traveling region, [m]",
61 DoubleValue(1),
64 .AddAttribute("MaxY",
65 "Maximum Y value of traveling region, [m]",
66 DoubleValue(1),
69 .AddAttribute("Z",
70 "Z value of traveling region (fixed), [m]",
71 DoubleValue(0.0),
74
75 return tid;
76}
77
92
97
98void
104
105void
107{
108 alreadyStarted = true;
109 // Configure random variables based on attributes
110 NS_ASSERT(m_minSpeed >= 1e-6);
112 m_speed->SetAttribute("Min", DoubleValue(m_minSpeed));
113 m_speed->SetAttribute("Max", DoubleValue(m_maxSpeed));
116 m_x->SetAttribute("Min", DoubleValue(m_minX));
117 m_x->SetAttribute("Max", DoubleValue(m_maxX));
118 m_y->SetAttribute("Min", DoubleValue(m_minY));
119 m_y->SetAttribute("Max", DoubleValue(m_maxY));
120 m_position->SetX(m_x);
121 m_position->SetY(m_y);
123 z->SetAttribute("Constant", DoubleValue(m_z));
124 m_position->SetZ(z);
125
127 m_pause->SetAttribute("Min", DoubleValue(m_minPause));
128 m_pause->SetAttribute("Max", DoubleValue(m_maxPause));
129
130 m_helper.Update();
131 m_helper.Pause();
132
133 // calculate the steady-state probability that a node is initially paused
134 double expectedPauseTime = (m_minPause + m_maxPause) / 2;
135 double a = m_maxX - m_minX;
136 double b = m_maxY - m_minY;
137 double v0 = m_minSpeed;
138 double v1 = m_maxSpeed;
139 double log1 = b * b / a * std::log(std::sqrt((a * a) / (b * b) + 1) + a / b);
140 double log2 = a * a / b * std::log(std::sqrt((b * b) / (a * a) + 1) + b / a);
141 double expectedTravelTime = 1.0 / 6.0 * (log1 + log2);
142 expectedTravelTime +=
143 1.0 / 15.0 * ((a * a * a) / (b * b) + (b * b * b) / (a * a)) -
144 1.0 / 15.0 * std::sqrt(a * a + b * b) * ((a * a) / (b * b) + (b * b) / (a * a) - 3);
145 if (v0 == v1)
146 {
147 expectedTravelTime /= v0;
148 }
149 else
150 {
151 expectedTravelTime *= std::log(v1 / v0) / (v1 - v0);
152 }
153 double probabilityPaused = expectedPauseTime / (expectedPauseTime + expectedTravelTime);
154 NS_ASSERT(probabilityPaused >= 0 && probabilityPaused <= 1);
155
156 double u = m_u_r->GetValue(0, 1);
157 if (u < probabilityPaused) // node initially paused
158 {
159 m_helper.SetPosition(m_position->GetNext());
160 u = m_u_r->GetValue(0, 1);
161 Time pause;
162 if (m_minPause != m_maxPause)
163 {
164 if (u < (2 * m_minPause / (m_minPause + m_maxPause)))
165 {
166 pause = Seconds(u * (m_minPause + m_maxPause) / 2);
167 }
168 else
169 {
170 // there is an error in equation 20 in the Tech. Report MCS-03-04
171 // this error is corrected in the TMC 2004 paper and below
172 pause = Seconds(m_maxPause - std::sqrt((1 - u) * (m_maxPause * m_maxPause -
174 }
175 }
176 else // if pause is constant
177 {
178 pause = Seconds(u * expectedPauseTime);
179 }
180 NS_ASSERT(!m_event.IsPending());
181 m_event =
183 }
184 else // node initially moving
185 {
186 double x1;
187 double x2;
188 double y1;
189 double y2;
190 x1 = x2 = y1 = y2 = 0;
191 double r = 0;
192 double u1 = 1;
193 while (u1 >= r)
194 {
195 x1 = m_x1_r->GetValue(0, a);
196 y1 = m_y1_r->GetValue(0, b);
197 x2 = m_x2_r->GetValue(0, a);
198 y2 = m_y2_r->GetValue(0, b);
199 u1 = m_u_r->GetValue(0, 1);
200 r = std::sqrt(((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) / (a * a + b * b));
201 NS_ASSERT(r <= 1);
202 }
203 double u2 = m_u_r->GetValue(0, 1);
204 m_helper.SetPosition(
205 Vector(m_minX + u2 * x1 + (1 - u2) * x2, m_minY + u2 * y1 + (1 - u2) * y2, m_z));
206 NS_ASSERT(!m_event.IsPending());
207 m_event =
209 this,
210 Vector(m_minX + x2, m_minY + y2, m_z));
211 }
213}
214
215void
217{
218 m_helper.Update();
219 Vector m_current = m_helper.GetCurrentPosition();
220 NS_ASSERT(m_minX <= m_current.x && m_current.x <= m_maxX);
221 NS_ASSERT(m_minY <= m_current.y && m_current.y <= m_maxY);
222 NS_ASSERT(m_minX <= destination.x && destination.x <= m_maxX);
223 NS_ASSERT(m_minY <= destination.y && destination.y <= m_maxY);
224 double u = m_u_r->GetValue(0, 1);
225 double speed = std::pow(m_maxSpeed, u) / std::pow(m_minSpeed, u - 1);
226 double dx = (destination.x - m_current.x);
227 double dy = (destination.y - m_current.y);
228 double dz = (destination.z - m_current.z);
229 double k = speed / std::sqrt(dx * dx + dy * dy + dz * dz);
230
231 m_helper.SetVelocity(Vector(k * dx, k * dy, k * dz));
232 m_helper.Unpause();
233 Time travelDelay = Seconds(CalculateDistance(destination, m_current) / speed);
234 m_event =
237}
238
239void
241{
242 m_helper.Update();
243 Vector m_current = m_helper.GetCurrentPosition();
244 NS_ASSERT(m_minX <= m_current.x && m_current.x <= m_maxX);
245 NS_ASSERT(m_minY <= m_current.y && m_current.y <= m_maxY);
246 Vector destination = m_position->GetNext();
247 double speed = m_speed->GetValue();
248 double dx = (destination.x - m_current.x);
249 double dy = (destination.y - m_current.y);
250 double dz = (destination.z - m_current.z);
251 double k = speed / std::sqrt(dx * dx + dy * dy + dz * dz);
252
253 m_helper.SetVelocity(Vector(k * dx, k * dy, k * dz));
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
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:440
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:66
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:561
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:595
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:94
a unique identifier for an interface.
Definition type-id.h:49
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
#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< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#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:1345
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeDoubleChecker()
Definition double.h:82
double CalculateDistance(const Vector3D &a, const Vector3D &b)
Definition vector.cc:98
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition double.h:32