DESERT 3.5.1
Loading...
Searching...
No Matches
uwopticalbeampattern.cpp
Go to the documentation of this file.
1//
2// Copyright (c) 2018 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
41#include <float.h>
42
43const double K = 1.38 * 1.E-23; // Boltzmann constant
44const double q = 1.6 * 1.E-19; // electronic charge
45
46static class UwOpticalBeamPatternClass : public TclClass
47{
48public:
50 : TclClass("Module/UW/UWOPTICALBEAMPATTERN")
51 {
52 }
53 TclObject *
54 create(int, const char *const *)
55 {
56 return (new UwOpticalBeamPattern);
57 }
59
61 :
63 beam_pattern_path_tx_(""),
64 beam_pattern_path_rx_(""),
65 max_dist_path_(""),
66 beam_pattern_separator_(','),
67 max_dist_separator_(','),
68 dist_lut_(),
69 beam_lut_tx_(),
70 beam_lut_rx_(),
71 back_noise_threshold_(0),
72 inclination_angle_(0),
73 sameBeam(true)
74{
75 bind("noise_threshold", &back_noise_threshold_);
76 bind("inclination_angle_", &inclination_angle_);
78}
79
80int
81UwOpticalBeamPattern::command(int argc, const char *const *argv)
82{
83 if (argc == 2) {
84 if (strcasecmp(argv[1], "useSameBeamPattern") == 0) {
85 sameBeam = true;
86 return TCL_OK;
87 } else if (strcasecmp(argv[1], "useDifferentBeamPattern") == 0) {
88 sameBeam = false;
89 return TCL_OK;
90 }
91
92 } else if (argc == 3) {
93 if (strcasecmp(argv[1], "setBeamPatternPath") == 0) {
94 if (!sameBeam) {
95 fprintf(stderr, "sameBeam set as false, 2 beam pattern paths needed");
96 return TCL_ERROR;
97 }
98 string tmp_ = ((char *) argv[2]);
99 if (tmp_.size() == 0) {
100 fprintf(stderr, "Empty string for the file name");
101 return TCL_ERROR;
102 }
103 std::cout << "Use same beam pattern for tx and rx" << std::endl;
106 return TCL_OK;
107 } else if (strcasecmp(argv[1], "setMaxRangePath") == 0) {
108 string tmp_ = ((char *) argv[2]);
109 if (tmp_.size() == 0) {
110 fprintf(stderr, "Empty string for the file name");
111 return TCL_ERROR;
112 }
113 max_dist_path_ = tmp_;
114 return TCL_OK;
115 } else if (strcasecmp(argv[1], "setBeamSeparator") == 0) {
116 string tmp_ = ((char *) argv[2]);
117 if (tmp_.size() == 0) {
118 fprintf(stderr, "Empty char for the file name");
119 return TCL_ERROR;
120 }
121 beam_pattern_separator_ = tmp_.at(0);
122 return TCL_OK;
123 } else if (strcasecmp(argv[1], "setMaxRangeSeparator") == 0) {
124 string tmp_ = ((char *) argv[2]);
125 if (tmp_.size() == 0) {
126 fprintf(stderr, "Empty char for the file name");
127 return TCL_ERROR;
128 }
129 max_dist_separator_ = tmp_.at(0);
130 return TCL_OK;
131 } else if (strcasecmp(argv[1], "setInclinationAngle") == 0) {
132 inclination_angle_ = atof(argv[2]);
134 return TCL_OK;
135 }
136 } else if (argc == 4) {
137 if (strcasecmp(argv[1], "setBeamPatternPath") == 0) {
138 if (sameBeam) {
139 fprintf(stderr, "sameBeam set as true, 1 beam pattern path needed");
140 return TCL_ERROR;
141 }
142 string tmp_tx = ((char *) argv[2]);
143 string tmp_rx = ((char *) argv[3]);
144 if (tmp_tx.size() == 0 || tmp_rx.size() == 0) {
145 fprintf(stderr, "Empty string for the file name");
146 return TCL_ERROR;
147 }
148 std::cout << "Use different LUTs for tx and rx" << std::endl;
149 beam_pattern_path_tx_ = tmp_tx;
150 beam_pattern_path_rx_ = tmp_rx;
151 return TCL_OK;
152 }
153 }
154 return UwOpticalPhy::command(argc, argv);
155}
156
157void
165
166void
168{
169 hdr_MPhy *ph = HDR_MPHY(p);
170 Position *source = ph->srcPosition;
171 Position *destination = ph->dstPosition;
172 double dist = source->getDist(destination);
173
174
175 if ((PktRx == 0) && (txPending == false)) {
176 double max_tx_range = getMaxTxRange(p);
177 if (debug_)
178 cout << NOW << " UwOpticalBeamPattern::startRx max_tx_range LUT = " << max_tx_range
179 << " distance = " << dist << endl;
180 if (max_tx_range > dist) {
181 if (ph->modulationType == MPhy_Bpsk::modid) {
182 PktRx = p;
183 Phy2MacStartRx(p);
184 return;
185 } else {
186 if (debug_)
187 cout << NOW << " UwOpticalBeamPattern::Drop Packet::Wrong modulation"
188 << endl;
189 }
190 } else {
191 if (debug_)
192 cout << NOW << " UwOpticalBeamPattern::Drop Packet::Distance = "
193 << dist
194 << ", Above Max Range = " << max_tx_range
195 << endl;
196 }
197 } else {
198 if (debug_)
199 cout << NOW << " UwOpticalBeamPattern::Drop Packet::Synced onto another packet "
200 "PktRx = "
201 << PktRx << ", pending = " << txPending << endl;
202 }
203}
204
205double
207{
208 double beta = getBetaRx(p);
209 //double beta_xy = getBetaXY(p, inclination_angle_);
210 double beta_xy = getBetaXYRx(p);
211
212 double c = ((UwOpticalMPropagation *) propagation_)->getC(p);
213
214 if (debug_)
215 cout << NOW << " UwOpticalBeamPattern::getMaxTxRange c = "
216 << c << std::endl;
217
219 double beta_tx = getBetaTx(p);
220 //double beta_xy_tx = getBetaXY(p, bl->get_inclination_angle());
221 double beta_xy_tx = getBetaXYTx(p);
222
223 hdr_MPhy *ph = HDR_MPHY(p);
224 Position *dest = ph->dstPosition;
225 double dest_depth = use_woss_ ? -dest->getAltitude() : -dest->getZ();
226 double na = lookUpLightNoiseE(dest_depth); // background noise
227
228 if ((dist_lut_.empty() == true) ||
229 beam_lut_tx_.empty() == true || beam_lut_rx_.empty() == true) {
230 cerr << "UwOpticalBeamPattern::getMaxTxRange error: LUTs not init." << endl;
231 return 0;
232 }
233 double max_distance = getLutMaxDist(c,na);
234 if (debug_)
235 cout << NOW << " UwOpticalBeamPattern::getMaxTxRange max_distance LUT = "
236 << max_distance << endl;
237 /*if(beta == 0) {
238 return max_distance;
239 }*/
240 double norm_beam_factor_rx = getLutBeamFactor(beam_lut_rx_, beta);
241 double norm_beam_factor_tx = getLutBeamFactor(beam_lut_tx_, beta_tx);
242 if (debug_)
243 cout << NOW << " UwOpticalBeamPattern::getMaxTxRange norm_beam_factor = "
244 << norm_beam_factor_rx << ", beta = " << beta << endl;
245 double norm_beam_factor_xy_rx = getLutBeamFactor(beam_lut_rx_, beta_xy);
246 double norm_beam_factor_xy_tx = getLutBeamFactor(beam_lut_tx_, beta_xy_tx);
247 if (debug_)
248 cout << NOW << " UwOpticalBeamPattern::getMaxTxRange norm_beam_factor_xy = "
249 << norm_beam_factor_xy_rx << ", beta_xy = " << beta_xy << endl;
250 return max_distance * norm_beam_factor_rx * norm_beam_factor_xy_rx
251 * norm_beam_factor_tx * norm_beam_factor_xy_tx;
252}
253
254double
256{
257 bool omnidirectional =
258 ((UwOpticalMPropagation *) propagation_)->isOmnidirectional();
259 if(omnidirectional) {
260 return 0;
261 }
262 hdr_MPhy *ph = HDR_MPHY(p);
263 Position *rx = ph->dstPosition;
264 Position *tx = ph->srcPosition;
265 double rx_x = use_woss_ ? rx->getLongitude() : rx->getX();
266 double tx_x = use_woss_ ? tx->getLongitude() : tx->getX();
267 double rx_y = use_woss_ ? rx->getLatitude() : rx->getY();
268 double tx_y = use_woss_ ? tx->getLatitude() : tx->getY();
269 double rx_depth = use_woss_ ? rx->getAltitude() : rx->getZ();
270 double tx_depth = use_woss_ ? tx->getAltitude() : tx->getZ();
271 double dx = tx_x - rx_x;
272 double dy = tx_y - rx_y;
273 double dz = tx_depth - rx_depth;
274 double dx_prime = dx*cos(-inclination_angle_) - dz*sin(-inclination_angle_);
275 double dz_prime = dx*sin(-inclination_angle_) + dz*cos(-inclination_angle_);
276 double dy_prime = dy;
277
278 double dist_xy = sqrt(dx_prime*dx_prime + dy_prime*dy_prime);
279 double beta = 0;
280 if (dist_xy == 0) {
281 beta = dz_prime > 0 ? M_PI/2 : - M_PI/2;
282 }
283 else {
284 beta = use_woss_ ?
285 ((UwOpticalMPropagation *) propagation_)->getBeta(p)
286 : atan(dz_prime/dist_xy);
287 }
288 beta = dz_prime == 0 ? 0 : beta;
289
290 if (dx_prime < 0) {
291 beta = beta > 0 ? beta - M_PI : beta + M_PI;
292 }
293 beta = beta > M_PI ? beta - 2 * M_PI
294 : beta < -M_PI ? beta + 2 * M_PI : beta;
295 return beta;
296}
297
298
299double
301{
302 bool omnidirectional =
303 ((UwOpticalMPropagation *) propagation_)->isOmnidirectional();
304 if(omnidirectional) {
305 return 0;
306 }
307 hdr_MPhy *ph = HDR_MPHY(p);
308 Position *rx = ph->dstPosition;
309 Position *tx = ph->srcPosition;
310 double rx_x = use_woss_ ? rx->getLongitude() : rx->getX();
311 double tx_x = use_woss_ ? tx->getLongitude() : tx->getX();
312 double rx_y = use_woss_ ? rx->getLatitude() : rx->getY();
313 double tx_y = use_woss_ ? tx->getLatitude() : tx->getY();
314 double rx_depth = use_woss_ ? rx->getAltitude() : rx->getZ();
315 double tx_depth = use_woss_ ? tx->getAltitude() : tx->getZ();
316 double dx = tx_x - rx_x;
317 double dy = tx_y - rx_y;
318 double dz = tx_depth - rx_depth;
319 double dx_prime = dx*cos(-inclination_angle_) - dz*sin(-inclination_angle_);
320 double dz_prime = dx*sin(-inclination_angle_) + dz*cos(-inclination_angle_);
321 double dy_prime = dy;
322
323
324
325 double beta_xy = 0;
326 if(dx_prime == 0) {
327 beta_xy = dy_prime > 0 ? M_PI/2 : - M_PI/2;
328 }
329 else {
330 beta_xy= atan((dy_prime)/(dx_prime));
331 }
332 beta_xy = dy_prime == 0 ? 0 : beta_xy;
333
334 return beta_xy;
335
336
337}
338
339double
341{
342 bool omnidirectional =
343 ((UwOpticalMPropagation *) propagation_)->isOmnidirectional();
344 if(omnidirectional) {
345 return 0;
346 }
347
348
350 hdr_MPhy *ph = HDR_MPHY(p);
351 Position *tx = ph->srcPosition;
352 Position *rx = ph->dstPosition;
353 double tx_x = use_woss_ ? tx->getLongitude() : tx->getX();
354 double rx_x = use_woss_ ? rx->getLongitude() : rx->getX();
355 double tx_y = use_woss_ ? tx->getLatitude() : tx->getY();
356 double rx_y = use_woss_ ? rx->getLatitude() : rx->getY();
357 double tx_depth = use_woss_ ? tx->getAltitude() : tx->getZ();
358 double rx_depth = use_woss_ ? rx->getAltitude() : rx->getZ();
359 double dx = rx_x - tx_x;
360 double dy = rx_y - tx_y;
361 double dz = rx_depth - tx_depth;
362 double dx_prime = dx*cos(-bl->get_inclination_angle()) - dz*sin(-bl->get_inclination_angle());
363 double dz_prime = dx*sin(-bl->get_inclination_angle()) + dz*cos(-bl->get_inclination_angle());
364 double dy_prime = dy;
365
366 double beta_xy = 0;
367 if(dx_prime == 0) {
368 beta_xy = dy_prime > 0 ? M_PI/2 : - M_PI/2;
369 }
370 else {
371 beta_xy= atan((dy_prime)/(dx_prime));
372 }
373 beta_xy = dy_prime == 0 ? 0 : beta_xy;
374
375 return beta_xy;
376
377}
378
379double
381{
382 double max_distance = 0;
383 CMaxDistIter c_dist_it = dist_lut_.lower_bound(c);
384 assert(c_dist_it != dist_lut_.end());
385 if (c_dist_it->first > c && c_dist_it != dist_lut_.begin()) {
386 double dist_next = na > back_noise_threshold_ ?
387 c_dist_it->second.max_range_with_noise :
388 c_dist_it->second.max_range;
389 double c_next = c_dist_it->first;
390 c_dist_it--;
391 double dist_prev = na > back_noise_threshold_ ?
392 c_dist_it->second.max_range_with_noise :
393 c_dist_it->second.max_range;
394 double c_prev = c_dist_it->first;
395 max_distance = linearInterpolator(c, c_prev, dist_prev, c_next, dist_next);
396 }
397 else {
398 max_distance = na > back_noise_threshold_ ?
399 c_dist_it->second.max_range_with_noise :
400 c_dist_it->second.max_range;
401 }
402 return max_distance;
403}
404
405double
407{
408 double beam_norm_d = 0;
409 BeamPatternIter beam_it = beam_lut_.lower_bound(beta);
410 assert(beam_it != beam_lut_.end());
411 if (beam_it->first > beta && beam_it != beam_lut_.begin()) {
412 double dist_next = beam_it->second;
413 double beta_next = beam_it->first;
414 beam_it--;
415 double dist_prev = beam_it->second;
416 double beta_prev = beam_it->first;
417 beam_norm_d = linearInterpolator(beta, beta_prev, dist_prev, beta_next, dist_next);
418 }
419 else {
420 beam_norm_d = beam_it->second;
421 }
422 return beam_norm_d;
423}
424void
432
433void
434UwOpticalBeamPattern::initializeBeamLUT(BeamPattern &beam_lut_, string beam_pattern_path_)
435{
436 ifstream input_file_;
437 string line_;
438 input_file_.open(beam_pattern_path_.c_str());
439 if (input_file_.is_open()) {
440 double beta;
441 double r;
442 while (std::getline(input_file_, line_)) {
443 ::std::stringstream line_stream(line_);
444 line_stream >> beta;
445 line_stream.ignore(256, beam_pattern_separator_);
446 line_stream >> r;
447 beam_lut_[beta] = r;
448 }
449 input_file_.close();
450 } else {
451 cerr << "Impossible to open file " << beam_pattern_path_ << endl;
452 }
453}
454
455void
457{
458 ifstream input_file_;
459 string line_;
460 input_file_.open(max_dist_path_.c_str());
461 if (input_file_.is_open()) {
462 double c;
463 double r;
464 double r_e;
465 while (std::getline(input_file_, line_)) {
466 ::std::stringstream line_stream(line_);
467 line_stream >> c;
468 line_stream.ignore(256, max_dist_separator_);
469 line_stream >> r;
470 line_stream.ignore(256, max_dist_separator_);
471 line_stream >> r_e;
472 MaxDist d;
473 d.max_range = r;
474 d.max_range_with_noise = r_e;
475 dist_lut_[c] = d;
476 }
477 input_file_.close();
478 } else {
479 cerr << "Impossible to open file " << max_dist_path_ << endl;
480 }
481}
482
483void
485{
488 UwOpticalPhy::startTx(p);
489}
490
491double
493{
494 /*
495 bool omnidirectional =
496 ((UwOpticalMPropagation *) propagation_)->isOmnidirectional();
497 if(omnidirectional) {
498 return 0;
499 }
500 */
502 hdr_MPhy *ph = HDR_MPHY(p);
503 Position *tx = ph->srcPosition;
504 Position *rx = ph->dstPosition;
505 double tx_x = use_woss_ ? tx->getLongitude() : tx->getX();
506 double rx_x = use_woss_ ? rx->getLongitude() : rx->getX();
507 double tx_y = use_woss_ ? tx->getLatitude() : tx->getY();
508 double rx_y = use_woss_ ? rx->getLatitude() : rx->getY();
509 double tx_depth = use_woss_ ? tx->getAltitude() : tx->getZ();
510 double rx_depth = use_woss_ ? rx->getAltitude() : rx->getZ();
511 double dx = rx_x - tx_x;
512 double dy = rx_y - tx_y;
513 double dz = rx_depth - tx_depth;
514 double dx_prime = dx*cos(-bl->get_inclination_angle()) - dz*sin(-bl->get_inclination_angle());
515 double dz_prime = dx*sin(-bl->get_inclination_angle()) + dz*cos(-bl->get_inclination_angle());
516 double dy_prime = dy;
517
518 double dist_xy = sqrt(dx_prime*dx_prime + dy_prime*dy_prime);
519 double beta = 0;
520 if (dist_xy == 0) {
521 beta = dz_prime > 0 ? M_PI/2 : - M_PI/2;
522 }
523 else {
524 beta = use_woss_ ?
525 ((UwOpticalMPropagation *) propagation_)->getBeta(p)
526 : atan(dz_prime/dist_xy);
527 }
528 beta = dz_prime == 0 ? 0 : beta;
529 if (dx_prime < 0) {
530 beta = beta > 0 ? beta - M_PI : beta + M_PI;
531 }
532 beta = beta > M_PI ? beta - 2 * M_PI
533 : beta < -M_PI ? beta + 2 * M_PI : beta;
534
535 return beta;
536}
TclObject * create(int, const char *const *)
double getMaxTxRange(Packet *p)
Get the transmission range in the current conditions.
void initializeLUT()
Inizialize all the LUTs.
virtual void startRx(Packet *p)
void initializeBeamLUT(BeamPattern &beam_lut_, string beam_pattern_path_)
Inizialize beam pattern LUT.
double inclination_angle_
Angle of inclination from the 0 Zenith.
double getLutMaxDist(double c, double na)
Get the maximum transmission range for these water properties.
double getLutBeamFactor(BeamPattern &beam_lut_, double beta)
virtual int command(int, const char *const *)
TCL command interpreter.
void initializeMaxRangeLUT()
Inizialize max range LUT.
virtual void startTx(Packet *p)
UwOpticalBeamPattern()
Constructor of UwMultiPhy class.
Class used to represents the UWOPTICAL_MPROPAGATION.
virtual void initializeLUT()
Inizialize LUT of c_variable values.
virtual double lookUpLightNoiseE(double depth)
bool use_woss_
Flag to set whether woss is employed.
virtual int command(int, const char *const *)
TCL command interpreter.
virtual double linearInterpolator(double x, double x1, double y1, double x2, double y2)
double max_range_with_noise
Definition of UwOpticalMPropagation class.
#define HDR_UWOPTICALBEAMPATTERN(p)
const double q
UwOpticalBeamPatternClass class_module_optical
const double K
Definition of UwOptical class.
CMaxDist::iterator CMaxDistIter
BeamPattern::iterator BeamPatternIter
::std::map< double, double > BeamPattern