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::init(NeighborCache* neighborCache)
00033 {
00034 this->neighborCache = neighborCache;
00035
00036 errorC = neighborCache->par("vivaldiErrorConst");
00037 coordC = neighborCache->par("vivaldiCoordConst");
00038 dimension = neighborCache->par("vivaldiDimConst");
00039 enableHeightVector = neighborCache->par("vivaldiEnableHeightVector");
00040 showVivaldiPosition = neighborCache->par("showVivaldiPosition");
00041
00042
00043 VivaldiCoordsInfo::setDimension(dimension);
00044 ownCoords = new VivaldiCoordsInfo();
00045
00046 for (uint32_t i = 0; i < dimension; i++) {
00047 ownCoords->setCoords(i, uniform(-.2, .2));
00048 }
00049 if (enableHeightVector) ownCoords->setHeightVector(0.0);
00050
00051 WATCH(*ownCoords);
00052
00053 globalStatistics = GlobalStatisticsAccess().get();
00054 };
00055
00056 void Vivaldi::processCoordinates(const simtime_t& rtt,
00057 const AbstractNcsNodeInfo& nodeInfo)
00058 {
00059 if (rtt <= 0.0) {
00060 std::cout << "Vivaldi::processCoordinates() called with rtt = "
00061 << rtt << std::endl;
00062 return;
00063 }
00064
00065 if (!dynamic_cast<const VivaldiCoordsInfo*>(&nodeInfo)) {
00066 throw cRuntimeError("Vivaldi coords needed!");
00067 }
00068 const VivaldiCoordsInfo& info =
00069 *(static_cast<const VivaldiCoordsInfo*>(&nodeInfo));
00070
00071
00072 double weight = (((ownCoords->getError() + info.getError()) == 0) ? 0 :
00073 (ownCoords->getError() / (ownCoords->getError() + info.getError())));
00074
00075
00076 double dist = ownCoords->getDistance(info).proximity;
00077
00078
00079 ownCoords->setError(calcError(rtt, dist, weight));
00080
00081
00082 double delta = calcDelta(rtt, dist, weight);
00083
00084
00085 if (dist > 0) {
00086 for (uint8_t i = 0; i < dimension; i++) {
00087 ownCoords->setCoords(i, ownCoords->getCoords(i) +
00088 (delta * (SIMTIME_DBL(rtt) - dist)) *
00089 ((ownCoords->getCoords(i) - info.getCoords(i)) /
00090 dist));
00091 }
00092 if(enableHeightVector) {
00093 ownCoords->setHeightVector(ownCoords->getHeightVector() +
00094 (delta * (SIMTIME_DBL(rtt) - dist)));
00095 }
00096 }
00097
00098 updateDisplay();
00099 }
00100
00101
00102 double Vivaldi::calcError(const simtime_t& rtt, double dist, double weight)
00103 {
00104 double relErr = 0;
00105 if (rtt != 0) {
00106
00107 relErr = fabs(dist - rtt) / rtt;
00108 }
00109
00110 return (relErr * errorC * weight) +
00111 ownCoords->getError() * (1 - errorC * weight);
00112 }
00113
00114
00115 double Vivaldi::calcDelta(const simtime_t& rtt, double dist, double weight)
00116 {
00117
00118 return coordC * weight;
00119 }
00120
00121
00122 Prox Vivaldi::getCoordinateBasedProx(const AbstractNcsNodeInfo& abstractInfo) const
00123 {
00124 return ownCoords->getDistance(abstractInfo);
00125 }
00126
00127
00128 AbstractNcsNodeInfo* Vivaldi::createNcsInfo(const std::vector<double>& coords) const
00129 {
00130 assert(coords.size() > 1);
00131 VivaldiCoordsInfo* info = new VivaldiCoordsInfo();
00132
00133 uint8_t i;
00134 for (i = 0; i < coords.size() - (enableHeightVector ? 2 : 1); ++i) {
00135 info->setCoords(i, coords[i]);
00136 }
00137 info->setError(coords[i++]);
00138
00139 if (enableHeightVector) {
00140 info->setHeightVector(coords[i]);
00141 }
00142
00143 return info;
00144 }
00145
00146
00147 void Vivaldi::updateDisplay()
00148 {
00149 char buf[60];
00150 sprintf(buf, "xi[0]: %f xi[1]: %f ", ownCoords->getCoords(0),
00151 ownCoords->getCoords(1));
00152 neighborCache->getDisplayString().setTagArg("t", 0, buf);
00153
00154
00155 if (showVivaldiPosition) {
00156 for (uint32_t i = 0; i < dimension; i++)
00157 neighborCache->getParentModule()
00158 ->getDisplayString().setTagArg("p", i,
00159 ownCoords->getCoords(i) * 1000);
00160 }
00161 }
00162
00163 void Vivaldi::finishVivaldi()
00164 {
00165 globalStatistics->addStdDev("Vivaldi: Errori(ei)", ownCoords->getError());
00166 }