DESERT 3.5.1
Loading...
Searching...
No Matches
woss-gmmobility-3d.cpp
Go to the documentation of this file.
1//
2// Copyright (c) 2012 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
37#include<rng.h>
38#include<cmath>
39#include<fstream>
40#include<iomanip>
41#include "woss-gmmobility-3d.h"
42
43
47static class WossGMMob3DClass : public TclClass {
48public:
52 WossGMMob3DClass() : TclClass("WOSS/GMMob3D") {}
53 TclObject* create(int, const char*const*) {
54 return (new WossGMMob3D());
55 }
57
59
60 if (module->wossgm_debug_) cout << NOW << " WossGMMob3D::UpdateTimerPosition(" << module->maddr << "), timer expire, curr_state = UpdatePositionTime(), next_state = update()" << endl;
61
62 module -> update();
63
64}
65
67 xFieldWidth_(0),
68 yFieldWidth_(0),
69 zFieldWidth_(0.0),
70 alpha_(0),
71 speedMean_(0),
74 updateTime_(0),
75 speed_(0),
76 direction_(0),
77 maddr(-1),
78 start_latitude(0.0),
79 start_longitude(0.0),
80 start_x(0.0),
81 start_y(0.0),
82 nextUpdateTime_(0.0),
84 mtrace_(0),
86 pitch_(0.0),
87 pitchMean_(0.0),
88 vx(0.0),
89 vy(0.0),
90 vz(0.0),
91 alphaPitch_(0.0),
92 sigmaPitch_(0.0),
93 zmin_(0.0)
94{
95 bind("xFieldWidth_", &xFieldWidth_);
96 bind("yFieldWidth_", &yFieldWidth_);
97 bind("zFieldWidth_", &zFieldWidth_);
98 bind("alpha_", &alpha_);
99 bind("alphaPitch_", &alphaPitch_);
100 bind("updateTime_", &updateTime_);
101 bind("directionMean_", &directionMean_);
102 bind("pitchMean_", &pitchMean_);
103 bind("zmin_", &zmin_);
104 bind("sigmaPitch_",&sigmaPitch_);
105 bind("wossgm_debug_",&wossgm_debug_);
106
108}
109
113
114int WossGMMob3D::command(int argc, const char*const* argv)
115{
116 Tcl& tcl = Tcl::instance();
117 if(argc == 3)
118 {
119 if(strcasecmp(argv[1], "bound") == 0)
120 {
121 if (strcasecmp(argv[2],"SPHERIC")==0)
122 bound_ = SPHERIC;
123 else
124 {
125 if (strcasecmp(argv[2],"THOROIDAL")==0)
127 else
128 {
129 if (strcasecmp(argv[2],"HARDWALL")==0)
131 else
132 {
133 if (strcasecmp(argv[2],"REBOUNCE")==0)
135 else
136 {
137 fprintf(stderr,"WossGMMob3D::command(%s), unrecognized bound_ type (%s)\n",argv[1],argv[2]);
138 exit(1);
139 }
140 }
141 }
142 }
143 return TCL_OK;
144 }
145 if(strcasecmp(argv[1], "speedMean") == 0)
146 {
147 speedMean_ = speed_ = atof(argv[2]);
148 return TCL_OK;
149 }
150 if(strcasecmp(argv[1], "maddr") == 0)
151 {
152 maddr = atoi(argv[2]);
153 return TCL_OK;
154 }
155 if(strcasecmp(argv[1], "startLatitude") == 0)
156 {
157 start_latitude = atof(argv[2]);
158 return TCL_OK;
159 }
160 if(strcasecmp(argv[1], "startLongitude") == 0)
161 {
162 start_longitude = atof(argv[2]);
163 return TCL_OK;
164 }
165 if(strcasecmp(argv[1], "mtrace") == 0)
166 {
167 mtrace_ = atoi(argv[2]);
168 return TCL_OK;
169 }
170 if(strcasecmp(argv[1], "mTraceOfNode") == 0)
171 {
172 mtrace_of_node_ = atoi(argv[2]);
173 return TCL_OK;
174 }
175 if(strcasecmp(argv[1], "gm3dTraceFile") == 0)
176 {
177 gm3dTraceFile= argv[2];
178 return TCL_OK;
179 }
180 }
181 else if(argc == 2) {
182 if(strcasecmp(argv[1], "start") == 0)
183 {
184 update();
185 return TCL_OK;
186 }
187
188 }
189
190 return Position::command(argc, argv);
191}
192
194{
195 start_x = (earth_radius - WossPosition::getDepth()) * sin((90.0 - start_latitude) * M_PI / 180.0) * cos (start_longitude * M_PI / 180.0);
196 if (wossgm_debug_) cout << "values of x0: " << setprecision(12) << start_x << endl;
197 return start_x;
198
199}
200
202{
203 start_y = (earth_radius - WossPosition::getDepth()) * sin((90.0 - start_latitude) * M_PI / 180.0) * sin (start_longitude * M_PI / 180.0);
204 if (wossgm_debug_) cout << "values of y0: " << setprecision(12) << start_y << endl;
205 return start_y;
206
207}
208
209void WossGMMob3D::setLat(double x_coord, double y_coord)
210{
211 double lati, longi;
212 longi = atan2(y_coord,x_coord) * 180.0 / M_PI;
213 lati = 90.0 - (asin ( x_coord / ((earth_radius - WossPosition::getDepth()) * cos ( longi * M_PI / 180.0 ))) * 180.0 / M_PI);
214 if (wossgm_debug_) cout << "New latitude lati(" << maddr << "): " << lati << endl;
215 WossPosition::setLatitude(lati);
216}
217
218void WossGMMob3D::setLong(double x_coord, double y_coord)
219{
220 double longi;
221 longi = atan2(y_coord,x_coord) * 180.0 / M_PI;
222 if (wossgm_debug_) cout << "New longitude (" << maddr << "): " << longi << endl;
223 WossPosition::setLongitude(longi);
224}
225
227{
228 double x1, x2, w, y1;
229 static double y2;
230 static int use_last = 0;
231 if (use_last)
232 {
233 y1 = y2;
234 use_last = 0;
235 }
236 else
237 {
238 do
239 {
240 x1 = 2.0 * RNG::defaultrng()->uniform_double() - 1.0;
241 x2 = 2.0 * RNG::defaultrng()->uniform_double() - 1.0;
242 w = x1 * x1 + x2 * x2;
243 } while ( w >= 1.0 );
244
245 w = sqrt( (-2.0 * log( w ) ) / w );
246 y1 = x1 * w;
247 y2 = x2 * w;
248 use_last = 1;
249 }
250 return(y1);
251}
252
254{
255 if (wossgm_debug_)
256 printf("WossGMMob3D::Update(%d), Update at (%.3f) old speed %.2f old direction %.2f \n", maddr, NOW, speed_, direction_);
257
258 x_coord = WossPosition::getX() - getStartX();
259 if (wossgm_debug_) printf ("x-coord(%d) value: %.6f \n", maddr, x_coord);
260
261 y_coord = WossPosition::getY() - getStartY();
262 if (wossgm_debug_) printf ("y-coord(%d) value: %.6f \n", maddr, y_coord);
263
264 z_coord = WossPosition::getDepth();
265 if (wossgm_debug_) printf ("z-coord(%d) value: %.6f \n", maddr, z_coord);
266
267 speed_ = (alpha_*speed_) + (((1.0-alpha_))*speedMean_) + (sqrt(1.0-pow(alpha_,2.0))*Gaussian());
268 direction_ = (alpha_*direction_) + (((1.0-alpha_))*directionMean_) + (sqrt(1.0-pow(alpha_,2.0))*Gaussian());
269
271
272 if (wossgm_debug_)
273 printf("WossGMMob3D::Update(%d), new speed %.2f new direction %.2f new pitch %.2f \n", maddr, speed_, direction_, pitch_);
274
275 //calculate velocity
276 vx = speed_ * cos(direction_) * cos(pitch_);
277 if (wossgm_debug_) cout << "velocity in x(" << maddr << "): " << vx << endl;
278
279 vy = speed_ * sin(direction_) * cos(pitch_);
280 if (wossgm_debug_) cout << "velocity in y(" << maddr << "): " << vy << endl;
281
282 vz = speed_*sin(pitch_);
283 if (wossgm_debug_) cout << "velocity in z(" << maddr << "): " << vz << endl;
284
285 // calculate new position
286 newx = x_coord + (vx * updateTime_);
287 if (wossgm_debug_) cout << "newx(" << maddr << ") value: " << newx << endl;
288
289 newy = y_coord + (vy * updateTime_);
290 if (wossgm_debug_) cout << "newy(" << maddr << ") value: " << newy << endl;
291
292 newz = z_coord + (vz * updateTime_);
293 if (wossgm_debug_) cout << "newz(" << maddr << ") value: " << newz << endl;
294
295 if (wossgm_debug_)
296 printf("WossGMMob3D::Update(%d), X:%.3f->%.3f Y:%.3f->%.3f Z:%.3f->%.3f \n", maddr, x_coord, newx, y_coord, newy, z_coord, newz);
297 // verify whether the new position has to be re-computed in order
298 // to maintain node position within the simulation
299
300 if ((newy > yFieldWidth_) || ( newy < 0))
301 {
302 switch (bound_)
303 {
304 case SPHERIC:
307 break;
308 case THOROIDAL:
312 newx = xFieldWidth_/2;
313 newy = yFieldWidth_/2;
314 newz = zFieldWidth_/2;
315 break;
316 case HARDWALL:
317 newy = newy<0?0:yFieldWidth_;
318 break;
319 case REBOUNCE:
320 if (newy>yFieldWidth_)
321 {
322 newy = 2*yFieldWidth_ - newy;
324 //direction_ += pi/4;
325 }else{
326 newy = 0 - newy;
327 y_coord = 0 - y_coord;
328 //direction_ -= pi/4;
329 }
330 direction_ *= -1.0;
331 break;
332 }
333 }
334
335 if ((newx > xFieldWidth_) || ( newx < 0))
336 {
337 switch (bound_)
338 {
339 case SPHERIC:
342 break;
343 case THOROIDAL:
347 newx = xFieldWidth_/2;
348 newy = yFieldWidth_/2;
349 newz = zFieldWidth_/2;
350 break;
351 case HARDWALL:
352 newx = newx<0?0:xFieldWidth_;
353 break;
354 case REBOUNCE:
355 if (newx > xFieldWidth_)
356 {
357 newx = 2*xFieldWidth_ - newx;
359 }else{
360 newx = 0 - newx;
361 x_coord = 0 - x_coord;
362 }
363 if (newy==y_coord)
364 {
365 if (newx>x_coord)
366 direction_ = 0;
367 else
368 direction_ = pi;
369 }else{
370 if (newy>y_coord)
372 else
374 }
375 break;
376 }
377 }
378
379 if ((newz > zFieldWidth_) || ( newz < zmin_))
380 {
381 switch (bound_)
382 {
383 case SPHERIC:
386 break;
387 case THOROIDAL:
391 newx = xFieldWidth_/2;
392 newy = yFieldWidth_/2;
393 newz = zFieldWidth_/2;
394 break;
395 case HARDWALL:
396 newz = newz<0?0:zFieldWidth_;
397 break;
398 case REBOUNCE:
399 if (newz > zFieldWidth_)
400 {
401 newz = 2*zFieldWidth_ - newz;
403 }else{
404 newz = 2*zmin_ - newz;
405 z_coord = 2*zmin_ - z_coord;
406 }
407 break;
408 }
409 }
410
411 if ((newx < 0.0)||(newx > xFieldWidth_)||(newy < 0.0)||(newy > yFieldWidth_)||(newz < zmin_)||(newz>zFieldWidth_)) {
412 cout << NOW << " WossGMMob3D::update(" << maddr << "), error in postion! Abort!! " << endl;
413 update();
414 }
415
416 if (wossgm_debug_) cout << NOW << " WossGMMob3D::Update("<< maddr << "), newx value is: " << newx << endl;
417 if (wossgm_debug_) cout << NOW << " WossGMMob3D::Update("<< maddr << "), newy value is: " << newy << endl;
418 if (wossgm_debug_) cout << NOW << " WossGMMob3D::Update("<< maddr << "), newy value is: " << newz << endl;
419
420 x_coord = newx + getStartX();
421 y_coord = newy + getStartY();
422 z_coord = newz;
423 if (wossgm_debug_) cout << NOW << " WossGMMob3D::Update("<< maddr << "), final x_coord value is: " << x_coord << endl;
424 if (wossgm_debug_) cout << NOW << " WossGMMob3D::Update("<< maddr << "), final y_coord value is: " << y_coord << endl;
425 if (wossgm_debug_) cout << NOW << " WossGMMob3D::Update("<< maddr << "), final z_coord value is: " << z_coord << endl;
426
429 WossPosition::setDepth(z_coord);
430
432
433 if (wossgm_debug_)
434 printf("WossGMMob3D::Update(%d), now %f, updateTime %f\n", maddr,NOW, updateTime_);
435
436 if (mtrace_) {
437 if (maddr == mtrace_of_node_) {
438 ofstream saveInFile(gm3dTraceFile.c_str(), ios::app);
439 saveInFile << NOW << "\t" << setprecision(12) << newx << "\t" << setprecision(12) << newy << "\t" << setprecision(12) << newz << endl;
440 saveInFile.close();
441 }
442 }
443
445}
double Gauss(double m, double sigma, int type)
TCL Hooks for the simulator.
TclObject * create(int, const char *const *)
WossGMMob3DClass()
Constructor of the class.
virtual void schedule(double val)
Update Time is scheduled using this method.
virtual void expire(Event *e)
This method tell the node what to do when update timer expire.
This class implements the Gauss Markov mobility model.
double direction_
Current value of the direction.
double speedMean_
Defines the mean value of the speed.
double Gaussian()
Method that returns a value from a normal random Gaussian variable.
double sigmaPitch_
Standard deviation in the z-axis.
int maddr
Mac address of the node whose movement we would like to trace.
BoundType bound_
Defines the behaviour of the node when it reaches the edge.
int mtrace_
Flag to enable trace.
virtual void setLong(double x_coord, double y_coord)
double alphaPitch_
Parameter to be used to vary the randomness in z-axis.
double vz
new velocity of a node respectively in x-axis, y-axis and z-axis.
double yFieldWidth_
Range of the y-axis of the field to be simulated.
virtual int command(int argc, const char *const *argv)
TCL command intepreter Moreover it inherits all the OTcl method of Position.
virtual double getStartX()
Method that return the current projection of the node on the x-axis.
virtual double getStartY()
Method that return the current projection of the node on the y-axis.
string gm3dTraceFile
Trace file information.
double alpha_
Parameter to be used to vary the randomness.
virtual ~WossGMMob3D()
Destructor of WossGMMob3D class.
int wossgm_debug_
Debug flag.
double newz
new position of a node respectively in x-axis, y-axis and z-axis.
virtual void update()
Method that updates both the position coordinates as function of the number of states to be evaluated...
double zFieldWidth_
Range of the z-axis of the field to be simulated.
double xFieldWidth_
Range of the x-axis of the field to be simulated.
double nextUpdateTime_
Intenal variable used to evaluate the steps to be computed.
double start_y
Internal variable.
double pitchMean_
Defines the mean value of the shifting in z-axis.
virtual void setLat(double x_coord, double y_coord)
Method that return the starting curtesian coordinates of the node on the x-axis and y-axis.
int mtrace_of_node_
The node whose movement pattern we want to trace.
WossGMMob3D()
Constructor of WossGMMob3D class.
double speed_
Current value of the speed.
UpdateTimerPosition update_timer_position
An object of UpdateTimerPosition class.
double updateTime_
Time between two update computation.
double zmin_
Minimum z-axis value.
double start_longitude
Starting longitude of the simualted area.
double directionMean_
Defines the mean value of the direction.
double start_x
Internal variable.
double pitch_
Current value of the pitch.
double start_latitude
Starting latitude of the simualted area.
Uwrandomlib randlib
double z_coord
Previous position of the node.
WossGMMob3DClass class_wossgmmob3d
This is a Gauss-Markov random mobility model designed to use with WOSS (World Ocean Simulation System...
#define pi
#define earth_radius
#define sgn(x)