Vivaldi.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00025 #include <cfloat>
00026
00027 #include <NeighborCache.h>
00028
00029 #include "Vivaldi.h"
00030
00031
00032 void Vivaldi::initVivaldi(NeighborCache* neighborCache)
00033 {
00034 this->neighborCache = neighborCache;
00035
00036 useSVivaldi = neighborCache->par("useSVivaldi");
00037 errorC = neighborCache->par("vivaldiErrorConst");
00038 coordC = neighborCache->par("vivaldiCoordConst");
00039 dimension = neighborCache->par("vivaldiDimConst");
00040 enableHeightVector = neighborCache->par("vivaldiEnableHeightVector");
00041 lossC = neighborCache->par("vivaldiLossConst");
00042 effectiveSample = neighborCache->par("vivaldiEffectiveSample");
00043 showVivaldiPosition = neighborCache->par("showVivaldiPosition");
00044 lossResetLimit = neighborCache->par("lossResetLimit");
00045
00046 if(enableHeightVector) dimension += 1;
00047
00048
00049 xi.resize(dimension);
00050 errori = 1.0;
00051 loss = 0;
00052
00053 for (uint32_t i = 0; i < dimension; i++) {
00054 xi[i] = uniform(-.2, .2);
00055 }
00056 if(enableHeightVector) xi[dimension - 1] = 0;
00057
00058 WATCH(errori);
00059 WATCH_VECTOR(xi);
00060 WATCH(loss);
00061
00062 globalStatistics = GlobalStatisticsAccess().get();
00063 };
00064
00065 void Vivaldi::processCoordinates(simtime_t rtt,
00066 const std::vector<double>& xj,
00067 double errorj)
00068 {
00069
00070 if (rtt <= 0.0) return;
00071
00072
00073 double dist = 0, sum = 0, delta = 0;
00074 double weight = (((errori + errorj) == 0) ?
00075 0 : (errori / (errori + errorj)));
00076
00077 uint32_t size = dimension;
00078 if(enableHeightVector) size -= 1;
00079
00080
00081 if (rtt != 0) {
00082 for (uint32_t i = 0; i < size; i++) {
00083 dist += pow(xi[i] - xj[i], 2);
00084 }
00085 dist = sqrt(dist);
00086 }
00087 if (enableHeightVector) dist += xi[size] + xj[size];
00088
00089
00090 if (useSVivaldi) {
00091
00092 sum = neighborCache->getAvgAbsPredictionError(xi, effectiveSample);
00093
00094
00095 errori = (sum * errorC) + errori * (1 - errorC);
00096
00097
00098 loss = lossC + (1 - lossC) * loss;
00099 if(fabs(dist-SIMTIME_DBL(rtt)) > lossResetLimit) loss = 0.0;
00100 delta = coordC * weight * (1 - loss);
00101 } else {
00102 double relErr = 0;
00103 if (rtt != 0) {
00104
00105 relErr = fabs(dist - rtt) / rtt;
00106 }
00107
00108 errori = (relErr * errorC * weight) + errori * (1 - errorC * weight);
00109
00110 delta = coordC * weight;
00111 }
00112
00113
00114 if (dist > 0) {
00115 for (uint32_t i = 0; i < size; i++) {
00116 xi[i] += (delta * (SIMTIME_DBL(rtt) - dist)) * ((xi[i] - xj[i]) / dist);
00117 }
00118 if(enableHeightVector) {
00119 xi[size] += (delta * (SIMTIME_DBL(rtt) - dist));
00120 if(xi[size] < 0) xi[size] = 0.0;
00121 }
00122 }
00123 updateDisplay();
00124 }
00125
00126 Prox Vivaldi::getCoordinateBasedProx(const NodeCoordsInfo& info)
00127 {
00128 double dist = 0.0, accuracy = 0.0;
00129 uint32_t size = info.coordinates.size();
00130 if(enableHeightVector) size -= 1;
00131
00132 for (uint32_t i = 0; i < size; i++) {
00133 dist += pow(xi[i] - info.coordinates[i], 2);
00134 }
00135 dist = sqrt(dist);
00136
00137 accuracy = 1 - ((info.coordErr + errori) / 2);
00138 if (info.coordErr >= 1.0 || errori >= 1.0) accuracy = 0.0;
00139 if (accuracy < 0) accuracy = 0.0;
00140 if (accuracy > 1) accuracy = 1;
00141
00142 if (enableHeightVector) return Prox(dist +
00143 xi[size] +
00144 info.coordinates[size],
00145 info.coordErr);
00146 return Prox(dist, accuracy);
00147 }
00148
00149
00150 void Vivaldi::updateDisplay()
00151 {
00152 char buf[60];
00153 sprintf(buf, "xi[0]: %f xi[1]: %f ", xi[0], xi[1]);
00154 neighborCache->getDisplayString().setTagArg("t", 0, buf);
00155
00156
00157 if (showVivaldiPosition) {
00158 for (uint32_t i = 0; i < dimension; i++)
00159 neighborCache->getParentModule()
00160 ->getDisplayString().setTagArg("p", i, xi[i] * 1000);
00161 }
00162 }
00163
00164 void Vivaldi::finishVivaldi()
00165 {
00166 globalStatistics->addStdDev("Vivaldi: Errori(ei)",errori);
00167 }