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