A Discrete-Event Network Simulator
API
gauss-markov-mobility-model.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009 Dan Broyles
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Dan Broyles <dbroyl01@ku.edu>
18  */
20 
21 #include "position-allocator.h"
22 
23 #include "ns3/double.h"
24 #include "ns3/pointer.h"
25 #include "ns3/simulator.h"
26 #include "ns3/string.h"
27 
28 #include <cmath>
29 
30 namespace ns3
31 {
32 
33 NS_OBJECT_ENSURE_REGISTERED(GaussMarkovMobilityModel);
34 
35 TypeId
37 {
38  static TypeId tid =
39  TypeId("ns3::GaussMarkovMobilityModel")
41  .SetGroupName("Mobility")
42  .AddConstructor<GaussMarkovMobilityModel>()
43  .AddAttribute("Bounds",
44  "Bounds of the area to cruise.",
45  BoxValue(Box(-100.0, 100.0, -100.0, 100.0, 0.0, 100.0)),
46  MakeBoxAccessor(&GaussMarkovMobilityModel::m_bounds),
47  MakeBoxChecker())
48  .AddAttribute("TimeStep",
49  "Change current direction and speed after moving for this time.",
50  TimeValue(Seconds(1.0)),
53  .AddAttribute(
54  "Alpha",
55  "A constant representing the tunable parameter in the Gauss-Markov model.",
56  DoubleValue(1.0),
58  MakeDoubleChecker<double>())
59  .AddAttribute("MeanVelocity",
60  "A random variable used to assign the average velocity.",
61  StringValue("ns3::UniformRandomVariable[Min=0.0|Max=1.0]"),
63  MakePointerChecker<RandomVariableStream>())
64  .AddAttribute("MeanDirection",
65  "A random variable used to assign the average direction.",
66  StringValue("ns3::UniformRandomVariable[Min=0.0|Max=6.283185307]"),
68  MakePointerChecker<RandomVariableStream>())
69  .AddAttribute("MeanPitch",
70  "A random variable used to assign the average pitch.",
71  StringValue("ns3::ConstantRandomVariable[Constant=0.0]"),
73  MakePointerChecker<RandomVariableStream>())
74  .AddAttribute("NormalVelocity",
75  "A gaussian random variable used to calculate the next velocity value.",
76  StringValue("ns3::NormalRandomVariable[Mean=0.0|Variance=1.0|Bound=10."
77  "0]"), // Defaults to zero mean, and std dev = 1, and bound to
78  // +-10 of the mean
80  MakePointerChecker<NormalRandomVariable>())
81  .AddAttribute(
82  "NormalDirection",
83  "A gaussian random variable used to calculate the next direction value.",
84  StringValue("ns3::NormalRandomVariable[Mean=0.0|Variance=1.0|Bound=10.0]"),
86  MakePointerChecker<NormalRandomVariable>())
87  .AddAttribute(
88  "NormalPitch",
89  "A gaussian random variable used to calculate the next pitch value.",
90  StringValue("ns3::NormalRandomVariable[Mean=0.0|Variance=1.0|Bound=10.0]"),
92  MakePointerChecker<NormalRandomVariable>());
93 
94  return tid;
95 }
96 
98 {
99  m_meanVelocity = 0.0;
100  m_meanDirection = 0.0;
101  m_meanPitch = 0.0;
103  m_helper.Unpause();
104 }
105 
106 void
108 {
109  if (m_meanVelocity == 0.0)
110  {
111  // Initialize the mean velocity, direction, and pitch variables
115  double cosD = std::cos(m_meanDirection);
116  double cosP = std::cos(m_meanPitch);
117  double sinD = std::sin(m_meanDirection);
118  double sinP = std::sin(m_meanPitch);
119  // Initialize the starting velocity, direction, and pitch to be identical to the mean ones
123  // Set the velocity vector to give to the constant velocity helper
125  Vector(m_Velocity * cosD * cosP, m_Velocity * sinD * cosP, m_Velocity * sinP));
126  }
127  m_helper.Update();
128 
129  // Get the next values from the gaussian distributions for velocity, direction, and pitch
130  double rv = m_normalVelocity->GetValue();
131  double rd = m_normalDirection->GetValue();
132  double rp = m_normalPitch->GetValue();
133 
134  // Calculate the NEW velocity, direction, and pitch values using the Gauss-Markov formula:
135  // newVal = alpha*oldVal + (1-alpha)*meanVal + sqrt(1-alpha^2)*rv
136  // where rv is a random number from a normal (gaussian) distribution
137  double one_minus_alpha = 1 - m_alpha;
138  double sqrt_alpha = std::sqrt(1 - m_alpha * m_alpha);
139  m_Velocity = m_alpha * m_Velocity + one_minus_alpha * m_meanVelocity + sqrt_alpha * rv;
140  m_Direction = m_alpha * m_Direction + one_minus_alpha * m_meanDirection + sqrt_alpha * rd;
141  m_Pitch = m_alpha * m_Pitch + one_minus_alpha * m_meanPitch + sqrt_alpha * rp;
142 
143  // Calculate the linear velocity vector to give to the constant velocity helper
144  double cosDir = std::cos(m_Direction);
145  double cosPit = std::cos(m_Pitch);
146  double sinDir = std::sin(m_Direction);
147  double sinPit = std::sin(m_Pitch);
148  double vx = m_Velocity * cosDir * cosPit;
149  double vy = m_Velocity * sinDir * cosPit;
150  double vz = m_Velocity * sinPit;
151  m_helper.SetVelocity(Vector(vx, vy, vz));
152 
153  m_helper.Unpause();
154 
156 }
157 
158 void
160 {
162  Vector position = m_helper.GetCurrentPosition();
163  Vector speed = m_helper.GetVelocity();
164  Vector nextPosition = position;
165  nextPosition.x += speed.x * delayLeft.GetSeconds();
166  nextPosition.y += speed.y * delayLeft.GetSeconds();
167  nextPosition.z += speed.z * delayLeft.GetSeconds();
168  if (delayLeft.GetSeconds() < 0.0)
169  {
170  delayLeft = Seconds(1.0);
171  }
172 
173  // Make sure that the position by the next time step is still within the boundary.
174  // If out of bounds, then alter the velocity vector and average direction to keep the position
175  // in bounds
176  if (m_bounds.IsInside(nextPosition))
177  {
179  }
180  else
181  {
182  if (nextPosition.x > m_bounds.xMax || nextPosition.x < m_bounds.xMin)
183  {
184  speed.x = -speed.x;
186  }
187 
188  if (nextPosition.y > m_bounds.yMax || nextPosition.y < m_bounds.yMin)
189  {
190  speed.y = -speed.y;
192  }
193 
194  if (nextPosition.z > m_bounds.zMax || nextPosition.z < m_bounds.zMin)
195  {
196  speed.z = -speed.z;
198  }
199 
202  m_helper.SetVelocity(speed);
203  m_helper.Unpause();
205  }
207 }
208 
209 void
211 {
212  // chain up
214 }
215 
216 Vector
218 {
219  m_helper.Update();
220  return m_helper.GetCurrentPosition();
221 }
222 
223 void
225 {
226  m_helper.SetPosition(position);
227  m_event.Cancel();
229 }
230 
231 Vector
233 {
234  return m_helper.GetVelocity();
235 }
236 
237 int64_t
239 {
240  m_rndMeanVelocity->SetStream(stream);
241  m_normalVelocity->SetStream(stream + 1);
242  m_rndMeanDirection->SetStream(stream + 2);
243  m_normalDirection->SetStream(stream + 3);
244  m_rndMeanPitch->SetStream(stream + 4);
245  m_normalPitch->SetStream(stream + 5);
246  return 6;
247 }
248 
249 } // namespace ns3
a 3d box
Definition: box.h:35
double yMax
The y coordinate of the top bound of the box.
Definition: box.h:116
bool IsInside(const Vector &position) const
Definition: box.cc:54
double xMin
The x coordinate of the left bound of the box.
Definition: box.h:110
double yMin
The y coordinate of the bottom bound of the box.
Definition: box.h:114
double xMax
The x coordinate of the right bound of the box.
Definition: box.h:112
double zMin
The z coordinate of the down bound of the box.
Definition: box.h:118
double zMax
The z coordinate of the up bound of the box.
Definition: box.h:120
Vector GetCurrentPosition() const
Get current position vector.
Vector GetVelocity() const
Get velocity; if paused, will return a zero vector.
void Update() const
Update position, if not paused, from last position and time of last update.
void UpdateWithBounds(const Rectangle &rectangle) const
Update position, if not paused, from last position and time of last update.
void Unpause()
Resume mobility from current position at current velocity.
void SetPosition(const Vector &position)
Set position vector.
void SetVelocity(const Vector &vel)
Set new velocity vector.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
void Cancel()
This method is syntactic sugar for the ns3::Simulator::Cancel method.
Definition: event-id.cc:55
Ptr< NormalRandomVariable > m_normalDirection
Gaussian rv for next direction value.
void DoDispose() override
Destructor implementation.
Ptr< NormalRandomVariable > m_normalPitch
Gaussian rv for next pitch.
void Start()
Initialize the model and calculate new velocity, direction, and pitch.
void DoWalk(Time timeLeft)
Perform a walk operation.
double m_meanVelocity
current mean velocity
double m_meanDirection
current mean direction
static TypeId GetTypeId()
Register this type with the TypeId system.
Ptr< NormalRandomVariable > m_normalVelocity
Gaussian rv used to for next velocity.
EventId m_event
event id of scheduled start
ConstantVelocityHelper m_helper
constant velocity helper
int64_t DoAssignStreams(int64_t) override
The default implementation does nothing but return the passed-in parameter.
Ptr< RandomVariableStream > m_rndMeanPitch
rv used to assign avg.
Ptr< RandomVariableStream > m_rndMeanVelocity
rv used to assign avg velocity
void DoSetPosition(const Vector &position) override
Ptr< RandomVariableStream > m_rndMeanDirection
rv used to assign avg direction
double m_alpha
tunable constant in the model
Time m_timeStep
duraiton after which direction and speed should change
Keep track of the current position and velocity of an object.
void NotifyCourseChange() const
Must be invoked by subclasses when the course of the position changes to notify course change listene...
virtual void DoDispose()
Destructor implementation.
Definition: object.cc:352
virtual double GetValue()=0
Get the next random value drawn from the distribution.
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:605
Hold variables of type string.
Definition: string.h:56
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1414
Ptr< const AttributeAccessor > MakePointerAccessor(T1 a1)
Definition: pointer.h:227
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43