DESERT 3.5.1
Loading...
Searching...
No Matches
uwgmposition.cpp
Go to the documentation of this file.
1//
2// Copyright (c) 2017 Regents of the SIGNET lab, University of Padova.
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions
7// are met:
8// 1. Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution.
13// 3. Neither the name of the University of Padova (SIGNET lab) nor the
14// names of its contributors may be used to endorse or promote products
15// derived from this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29
40#include "uwgmposition.h"
41
42#include <rng.h>
43#include <cmath>
44#include <time.h>
45#include <stdio.h>
46#include <stdlib.h>
47
51static class UwGMPositionClass : public TclClass
52{
53public:
55 : TclClass("Position/UWGM")
56 {
57 }
58
59 TclObject *
60 create(int, const char *const *)
61 {
62 return (new UwGMPosition());
63 }
65
67 : Position()
68 , xFieldWidth_(0.0)
69 , yFieldWidth_(0.0)
70 , zFieldWidth_(0.0)
71 , alpha_(0.0)
72 , alphaPitch_(0.0)
73 , speedMean_(0.0)
74 , directionMean_(0.0)
75 , pitchMean_(0.0)
76 , bound_(REBOUNCE)
77 , updateTime_(0)
78 , nextUpdateTime_(0.0)
79 , speed_(0)
80 , direction_(0)
81 , pitch_(0.0)
82 , debug_(0)
83 , vx(0.0)
84 , vy(0.0)
85 , vz(0.0)
86{
87 bind("xFieldWidth_", &xFieldWidth_);
88 bind("yFieldWidth_", &yFieldWidth_);
89 bind("zFieldWidth_", &zFieldWidth_);
90 bind("alpha_", &alpha_);
91 bind("alphaPitch_", &alphaPitch_);
92 bind("updateTime_", &updateTime_);
93 bind("directionMean_", &directionMean_);
94 bind("pitchMean_", &pitchMean_);
95 bind("debug_", &debug_);
96}
97
101
102int
103UwGMPosition::command(int argc, const char *const *argv)
104{
105 if (argc == 3) {
106 if (strcasecmp(argv[1], "bound") == 0) {
107 if (strcasecmp(argv[2], "SPHERIC") == 0)
108 bound_ = SPHERIC;
109 else {
110 if (strcasecmp(argv[2], "THOROIDAL") == 0)
112 else {
113 if (strcasecmp(argv[2], "HARDWALL") == 0)
115 else {
116 if (strcasecmp(argv[2], "REBOUNCE") == 0)
118 else {
119 fprintf(stderr,
120 "UwGMPosition::command(%s), unrecognized "
121 "bound_ type (%s)\n",
122 argv[1],
123 argv[2]);
124 exit(1);
125 }
126 }
127 }
128 }
129 return TCL_OK;
130 }
131 if (strcasecmp(argv[1], "speedMean") == 0) {
132 speedMean_ = speed_ = atof(argv[2]);
133 return TCL_OK;
134 }
135 }
136 return Position::command(argc, argv);
137}
138
139double
141{
142 return RNG::defaultrng()->normal(0.0,1.0);
143}
144
145
146void
148{
149 double t;
150 for (t = nextUpdateTime_; t < now; t += updateTime_) {
151 // calculate new sample of speed and direction
152 if (debug_ > 10)
153 printf("Update at %.3f(%.3f) old speed %.2f old direction %.2f old "
154 "pitch %.2f\n",
155 now,
156 t,
157 speed_,
159 pitch_);
160 speed_ = (alpha_ * speed_) + (((1.0 - alpha_)) * speedMean_) +
161 (sqrt(1.0 - pow(alpha_, 2.0)) * Gaussian());
163 (((1.0 - alpha_)) * directionMean_) +
164 (sqrt(1.0 - pow(alpha_, 2.0)) * Gaussian());
165 pitch_ = (alphaPitch_ * pitch_) + (((1.0 - alphaPitch_)) * pitchMean_) +
166 (sqrt(1.0 - pow(alphaPitch_, 2.0)) * Gaussian());
167
168 // calculate velocity
169 vx = speed_ * cos(direction_) * cos(pitch_);
170 vy = speed_ * sin(direction_) * cos(pitch_);
171 vz = speed_ * sin(pitch_);
172 // calculate new position
173 double newx = x_ + (vx * updateTime_);
174 double newy = y_ + (vy * updateTime_);
175 double newz = z_ + (vz * updateTime_);
176
177 if (debug_ > 10)
178 printf("X:%.3f->%.3f Y:%.3f->%.3f Z:%.3f->%.3f\n",
179 x_,
180 newx,
181 y_,
182 newy,
183 z_,
184 newz);
185 // verify whether the new position has to be re-computed in order
186 // to maintain node position within the simulation field
187
188 if ((newy > yFieldWidth_) || (newy < 0)) {
189 switch (bound_) {
190 case SPHERIC:
191 y_ -= yFieldWidth_ * (sgn(newy));
192 newy -= yFieldWidth_ * (sgn(newy));
193 break;
194 case THOROIDAL:
195 x_ = (xFieldWidth_ / 2) + x_ - newx;
196 y_ = (yFieldWidth_ / 2) + y_ - newy;
197 z_ = (zFieldWidth_ / 2) + z_ - newz;
198 newx = xFieldWidth_ / 2;
199 newy = yFieldWidth_ / 2;
200 newz = zFieldWidth_ / 2;
201 break;
202 case HARDWALL:
203 newy = newy < 0 ? 0 : yFieldWidth_;
204 break;
205 case REBOUNCE:
206 if (newy > yFieldWidth_) {
207 newy = 2 * yFieldWidth_ - newy;
208 y_ = 2 * yFieldWidth_ - y_;
209 } else {
210 newy = 0 - newy;
211 y_ = 0 - y_;
212 }
213 direction_ *= -1.0;
214 break;
215 }
216 }
217 if ((newx > xFieldWidth_) || (newx < 0)) {
218 switch (bound_) {
219 case SPHERIC:
220 x_ -= xFieldWidth_ * (sgn(newx));
221 newx -= xFieldWidth_ * (sgn(newx));
222 break;
223 case THOROIDAL:
224 x_ = (xFieldWidth_ / 2) + x_ - newx;
225 y_ = (yFieldWidth_ / 2) + y_ - newy;
226 z_ = (zFieldWidth_ / 2) + z_ - newz;
227 newx = xFieldWidth_ / 2;
228 newy = yFieldWidth_ / 2;
229 newz = zFieldWidth_ / 2;
230 break;
231 case HARDWALL:
232 newx = newx < 0 ? 0 : xFieldWidth_;
233 break;
234 case REBOUNCE:
235 if (newx > xFieldWidth_) {
236 newx = 2 * xFieldWidth_ - newx;
237 x_ = 2 * xFieldWidth_ - x_;
238 } else {
239 newx = 0 - newx;
240 x_ = 0 - x_;
241 }
242 if (newy == y_) {
243 if (newx > x_)
244 direction_ = 0;
245 else
246 direction_ = pi;
247 } else {
248 if (newy > y_)
250 else
252 }
253 break;
254 }
255 }
256 if ((newz > zFieldWidth_) || (newz < 0)) {
257 switch (bound_) {
258 case SPHERIC:
259 z_ -= zFieldWidth_ * (sgn(newz));
260 newz -= zFieldWidth_ * (sgn(newz));
261 break;
262 case THOROIDAL:
263 x_ = (xFieldWidth_ / 2) + x_ - newx;
264 y_ = (yFieldWidth_ / 2) + y_ - newy;
265 z_ = (zFieldWidth_ / 2) + z_ - newz;
266 newx = xFieldWidth_ / 2;
267 newy = yFieldWidth_ / 2;
268 newz = zFieldWidth_ / 2;
269 break;
270 case HARDWALL:
271 newz = newz < 0 ? 0 : zFieldWidth_;
272 break;
273 case REBOUNCE:
274 if (newz > zFieldWidth_) {
275 newz = 2 * zFieldWidth_ - newz;
276 z_ = 2 * zFieldWidth_ - z_;
277 } else {
278 ;
279 }
280 break;
281 }
282 }
283 x_ = newx;
284 y_ = newy;
285 z_ = newz;
287 }
288 nextUpdateTime_ = t;
289 if (debug_ > 10)
290 printf("nextUpdateTime = %f, now %f, updateTime %f\n",
292 now,
294}
295
296double
298{
299 double now = Scheduler::instance().clock();
300 if (now > nextUpdateTime_)
301 update(now);
302 return (x_);
303}
304
305double
307{
308 double now = Scheduler::instance().clock();
309 if (now > nextUpdateTime_)
310 update(now);
311 return (y_);
312}
313
314double
316{
317 double now = Scheduler::instance().clock();
318 if (now > nextUpdateTime_)
319 update(now);
320 return (z_);
321}
Adds the module for UwGMPositionClass in ns2.
TclObject * create(int, const char *const *)
UwGMPosition class implements the Gauss Markov 3D mobility model.
virtual void update(double now)
Method that updates both the position coordinates as function of the number of states to be evaluated...
double Gaussian()
Method that returns a value from a normal random Gaussian variable (zero mean, unitary viariance)
double vx
Temporary variable.
double vz
Temporary variable.
virtual int command(int argc, const char *const *argv)
TCL command interpreter.
double alpha_
Parameter to be used to vary the randomness: 0: totally random values (Brownian motion),...
int debug_
Flag to enable or disable dirrefent levels of debug.
double speedMean_
Defines the mean value of the speed, when it is setted to zero the node moves anyway.
double pitchMean_
Mean value for the pitch.
double direction_
Current value of the direction.
virtual ~UwGMPosition()
Destructor of UwGMPosition class.
virtual double getX()
Returns the current projection of the node on the x-axis.
UwGMPosition()
Constructor of UwGMPosition class.
BoundType bound_
double directionMean_
Defines the mean value of the direction.
double yFieldWidth_
Range of the y-axis of the field to be simulated, in meters.
double nextUpdateTime_
Internal variable used to evaluate the steps to be computed.
virtual double getY()
Returns the current projection of the node on the y-axis.
double vy
Temporary variable.
virtual double getZ()
Returns the current projection of the node on the z-axis.
double speed_
Current value of the speed.
double xFieldWidth_
Range of the x-axis of the field to be simulated, in meters.
double zFieldWidth_
Range of the z-axis of the field to be simulated, in meters.
double updateTime_
Defines the behaviour of the node when it reaches the edge: SPHERIC: return in the simulation field o...
double pitch_
Current value of the pitch.
double alphaPitch_
Pitch of alpha variable.
UwGMPositionClass class_uwgmposition
3D Gauss Markov mobility model.
#define pi
@ THOROIDAL
@ SPHERIC
@ REBOUNCE
@ HARDWALL
#define sgn(x)