DESERT 3.5.1
Loading...
Searching...
No Matches
uwhermesphy.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
39#include "uwhermesphy.h"
40#include <fstream>
41#include <sstream>
42
46static class UwHermesPhyClass : public TclClass
47{
48public:
50 : TclClass("Module/UW/HERMES/PHY")
51 {
52 }
53 TclObject *
54 create(int, const char *const *)
55 {
56 return (new UwHermesPhy);
57 }
59/*
60L{ 25, 50, 95, 120, 140, 160, 180, 190 },
61P_SUCC{ 0.923077*39/40, 0.913793*58/60, 0.924528*53/60, 0.876712*73/80,
62 0.61643*73/80, 0.75*28/40, 0.275862*29/40, 0 }*/
65 , pdr_file_name_("dbs/hermes/default.csv")
66 , pdr_token_separator_('\t')
67 , initLUT_(false)
68{ // binding to TCL variables
69 bind("BCH_N", &BCH_N);
70 bind("BCH_N", &BCH_K);
71 bind("BCH_N", &BCH_T);
72 bind("FRAME_BIT", &FRAME_BIT);
73 Interference_Model = "MEANPOWER";
74}
75
79
80int
81UwHermesPhy::command(int argc, const char *const *argv)
82{
83 if (argc == 2) {
84 if (strcasecmp(argv[1], "initLUT") == 0) {
86 return TCL_OK;
87 }
88 } else if (argc == 3) {
89 if (strcasecmp(argv[1], "setLUTFileName") == 0) {
90 string tmp_ = ((char *) argv[2]);
91 if (tmp_.size() == 0) {
92 fprintf(stderr, "Empty string for the file name");
93 return TCL_ERROR;
94 }
95 pdr_file_name_ = tmp_;
96 return TCL_OK;
97 } else if (strcasecmp(argv[1], "setLUTSeparator") == 0) {
98 string tmp_ = ((char *) argv[2]);
99 if (tmp_.size() == 0) {
100 fprintf(stderr, "Empty char for the file name");
101 return TCL_ERROR;
102 }
103 pdr_token_separator_ = tmp_.at(0);
104 return TCL_OK;
105 }
106 }
107 return UnderwaterPhysical::command(argc, argv);
108}
109
110void
112{
113 ifstream input_file_;
114 string line_;
115 char *tmp_ = new char[pdr_file_name_.length() + 1];
116 strcpy(tmp_, pdr_file_name_.c_str());
117 input_file_.open(tmp_);
118 if (input_file_.is_open()) {
119 // skip first 2 lines
120 if (debug_)
121 std::cout << "UwHermesPhy::initializeLUT()" << endl;
122 while (std::getline(input_file_, line_)) {
123 // TODO: retrive the right row and break the loop
124 ::std::stringstream line_stream(line_);
125 double d;
126 double p;
127 line_stream >> d;
128 line_stream >> p;
129 range2pdr_[d] = p;
130 if (debug_)
131 std::cout << d << " " << p << endl;
132 }
133 } else {
134 cerr << "Impossible to open file " << pdr_file_name_ << endl;
135 }
136 initLUT_ = true;
137}
138
139void
141{
142 if (!initLUT_)
143 cerr << "UwHermesPhy ERROR: FIRST INITIALIZE LUT!" << endl;
144 hdr_cmn *ch = HDR_CMN(p);
145 hdr_MPhy *ph = HDR_MPHY(p);
146 hdr_mac *mach = HDR_MAC(p);
147 counter interferent_pkts;
148 static int mac_addr = -1;
149 ClMsgPhy2MacAddr msg;
150 sendSyncClMsg(&msg);
151 mac_addr = msg.getAddr();
152 if (PktRx != 0) {
153 if (PktRx == p) {
154 double per_ni; // packet error rate due to noise and/or interference
155 double per_n; // packet error rate due to noise only
156 int nbits = ch->size() * 8;
157 double x = RNG::defaultrng()->uniform_double();
158 per_n = getPER(ph->Pr / ph->Pn, nbits, p);
159 bool error_n = x <= per_n;
160 bool error_ni = 0;
161 if (!error_n) {
162 if (interference_) {
163 if (Interference_Model == "MEANPOWER") { // only meanpower
164 // is allow in
165 // Hermesphy
166 double interference =
168 per_ni = interference > 0; // the Hermes interference
169 // model is unknown, thus it
170 // is taken as always
171 // destructive
172 if (per_ni and debug_)
173 std::cout << "INTERF" << interference << std::endl;
174 } else {
175 std::cerr << "Please choose only MEANPOWER as "
176 "Interference_Model"
177 << std::endl;
178 exit(1);
179 }
180 interferent_pkts = interference_->getCounters(p);
181
182 } else {
183 per_ni = getPER(ph->Pr / (ph->Pn + ph->Pi),
184 nbits,
185 p); // PER of Hermes acoustic modem
186 error_ni = x <= per_ni;
187 }
188 }
189 if (time_ready_to_end_rx_ > Scheduler::instance().clock()) {
190 Rx_Time_ = Rx_Time_ + ph->duration - time_ready_to_end_rx_ +
191 Scheduler::instance().clock();
192 } else {
193 Rx_Time_ += ph->duration;
194 }
196 Scheduler::instance().clock() + ph->duration;
197 Energy_Rx_ += consumedEnergyRx(ph->duration);
198
199 ch->error() = error_ni || error_n;
200 if (debug_) {
201 if (error_ni == 1) {
202 std::cout
203 << NOW << " UwHermesPhy(" << mac_addr
204 << ")::endRx() packet " << ch->uid()
205 << " contains errors due to noise and interference."
206 << std::endl;
207 } else if (error_n == 1) {
208 std::cout << NOW << " UwHermesPhy(" << mac_addr
209 << ")::endRx() packet " << ch->uid()
210 << " contains errors due to noise." << std::endl;
211 }
212 }
213 if (error_n) {
214 incrErrorPktsNoise();
215 if (mach->ftype() != MF_CONTROL) {
217 } else if (mach->ftype() == MF_CONTROL) {
219 }
220 } else if (error_ni) {
221 if (mach->ftype() != MF_CONTROL) {
222 incrErrorPktsInterf();
224 if (interferent_pkts.second >= 1) {
226 } else {
227 if (interferent_pkts.first > 0) {
229 }
230 }
231 } else if (mach->ftype() == MF_CONTROL) {
234 if (interferent_pkts.first > 0) {
236 }
237 }
238 }
239 sendUp(p);
240 PktRx = 0;
241 } else {
242 dropPacket(p);
243 }
244 } else {
245 dropPacket(p);
246 }
247}
248
249double
250UwHermesPhy::getPER(double _snr, int _nbits, Packet *_p)
251{
252 double distance = getDistance(_p);
253 return 1 - matchPS(distance, _nbits);
254}
255
256double
258{
259 hdr_MPhy *ph = HDR_MPHY(_p);
260 double x_src = (ph->srcPosition)->getX();
261 double y_src = (ph->srcPosition)->getY();
262 double z_src = (ph->srcPosition)->getZ();
263 double x_dst = (ph->dstPosition)->getX();
264 double y_dst = (ph->dstPosition)->getY();
265 double z_dst = (ph->dstPosition)->getZ();
266 return sqrt(pow(x_src - x_dst, 2.0) + pow(y_src - y_dst, 2.0) +
267 pow(z_src - z_dst, 2.0));
268}
269
270double
271UwHermesPhy::matchPS(double distance, int size)
272{ // success probability of Hermes
273 if (debug_)
274 /* std::cout << NOW << " UnderwaterPhysical(" << mac_addr <<
275 ")::matchPS(double distance, int size)"
276 << "distance = " << distance << " packet size = " << size <<;*/
277 std::cout << NOW
278 << " UwHermesPhy()::matchPS(double distance, int size)"
279 << "distance = " << distance << " packet size = " << size
280 << std::endl;
281 if (distance <= range2pdr_.begin()->first)
282 return chunckInterpolator(range2pdr_.begin()->second, size);
283
284 PdrLut::iterator it = range2pdr_.lower_bound(distance);
285 if (it == range2pdr_.end())
286 return chunckInterpolator((--it)->second, size);
287 double l_sup = it->first;
288 double p_sup = it->second;
289 it--;
290 double l_inf = it->first;
291 double p_inf = it->second;
292 if (debug_) {
293 std::cout << " Distance between " << l_inf << " and " << l_sup;
294 std::cout << " Succ Prob between " << p_inf << " and " << p_sup;
295 }
296 double p_succ_frame =
297 linearInterpolator(distance, l_inf, p_inf, l_sup, p_sup);
298 if (debug_)
299 std::cout << " Psucc_frame = " << p_succ_frame;
300 double ps = chunckInterpolator(p_succ_frame, size);
301 if (debug_)
302 std::cout << " Ps = " << ps << std::endl;
303 return ps;
304}
305
306double
308 double x, double x1, double y1, double x2, double y2)
309{
310 double m = (y1 - y2) / (x1 - x2);
311 double q = y1 - m * x1;
312 if (debug_)
313 /* std::cout << NOW << " UnderwaterPhysical(" << mac_addr <<
314 ")::linearInterpolator( double x, double x1, double y1, double x2,
315 double y2 )"
316 << "m = " << m << " q= " << q << std::endl;*/
317 std::cout << NOW << " UwHermesPhy::linearInterpolator( double x, "
318 "double x1, double y1, double x2, double y2 )"
319 << "m = " << m << " q= " << q << std::endl;
320 return m * x + q;
321}
322
323double
325{
326 int n_chunck_coded_frame = ceil(float(FRAME_BIT) / 11); // BCH(15,11,1)
327 int n_chunck_coded_packet = ceil(float(size) / 11);
328 if (debug_)
329 /* std::cout << NOW << " UnderwaterPhysical(" << mac_addr <<
330 ")::chunckInterpolator( double p, int size ) n_chunck_coded_frame = "
331 << n_chunck_coded_frame << " n_chunck_coded_packet = " <<
332 n_chunck_coded_packet << std::endl;*/
333 std::cout << NOW << " UwHermesPhy::chunckInterpolator( " << p << " "
334 << size << ") n_chunck_coded_frame = " << n_chunck_coded_frame
335 << " n_chunck_coded_packet = " << n_chunck_coded_packet
336 << std::endl;
337 return pow(p, (float(n_chunck_coded_packet) / n_chunck_coded_frame));
338}
void incrTot_pkts_lost()
Increment the number of packets discarded.
Definition uwphysical.h:295
std::string Interference_Model
Interference calcuation mode chosen: CHUNK model or MEANPOWER model.
Definition uwphysical.h:463
virtual double consumedEnergyRx(const double &_duration)
Compute the energy (in Joule) spent by the modem in reception.
Definition uwphysical.h:200
uwinterference * interference_
Pointer to the interference model module.
Definition uwphysical.h:467
void incrErrorCtrlPktsInterf()
Increment the number of CTRL packets discarded due to interference.
Definition uwphysical.h:313
double Energy_Rx_
Energy (in Joule) spent by the node in transmission.
Definition uwphysical.h:441
void incrCollisionCTRL()
Increment the number of CTRL pkts discarded due to a collision.
Definition uwphysical.h:331
void incrCollisionDATAvsCTRL()
Increment the number of collisions DATA/CTRL.
Definition uwphysical.h:322
double time_ready_to_end_rx_
Used to keep track of the arrival time.
Definition uwphysical.h:430
double Rx_Time_
Time (in seconds) spent by the node in reception.
Definition uwphysical.h:435
virtual int command(int, const char *const *)
TCL command interpreter.
void incrCollisionDATA()
Increment the number of DATA pkts discarded due to a collision.
Definition uwphysical.h:340
void incrTotCrtl_pkts_lost()
Increment the number of CTRL packets discarded.
Definition uwphysical.h:304
Adds the module for UwCbrModuleClass in ns2.
TclObject * create(int, const char *const *)
string pdr_file_name_
virtual void initializeLUT()
virtual double matchPS(double distance, int size)
Return the PER via linear interpolation.
virtual void endRx(Packet *p)
Handles the end of a packet reception.
PdrLut range2pdr_
virtual int command(int, const char *const *)
TCL command interpreter.
virtual double linearInterpolator(double x, double x1, double y1, double x2, double y2)
Return y via linear interpolation given two points.
UwHermesPhy()
Constructor of UwHermesPhy class.
virtual double getDistance(Packet *)
Return the distance between source and destination.
virtual double getPER(double snr, int nbits, Packet *)
Returns the packet error rate by using the length of a packet and the information contained in the pa...
virtual double chunckInterpolator(double p, int size)
int BCH_N
BCH(n,k,t) : correction of t errors via BCH code new frame length= FRAME_BIT/k*n, example: 9152/11*15...
virtual ~UwHermesPhy()
Destructor of UwHermesPhy class.
char pdr_token_separator_
virtual counter getCounters(Packet *p)
Returns the counters of collisions.
virtual double getInterferencePower(Packet *p)
Compute the average interference power for the given packet.
UwHermesPhyClass class_module_uwhermesphy
Definition of UwHermesPhy class.
std::pair< int, int > counter
counter of collisions
const double q