Vivaldi.cc

Go to the documentation of this file.
00001 // Copyright (C) 2008 Institut fuer Telematik, Universitaet Karlsruhe (TH)
00002 //
00003 // This program is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU General Public License
00005 // as published by the Free Software Foundation; either version 2
00006 // of the License, or (at your option) any later version.
00007 //
00008 // This program is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 // GNU General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this program; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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     // init variables
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     // calculate weight
00072     double weight = (((ownCoords->getError() + info.getError()) == 0) ? 0 :
00073         (ownCoords->getError() / (ownCoords->getError() + info.getError())));
00074 
00075     // calculate distance
00076     double dist = ownCoords->getDistance(info).proximity;
00077 
00078     // ... own error
00079     ownCoords->setError(calcError(rtt, dist, weight));
00080 
00081     // delta
00082     double delta = calcDelta(rtt, dist, weight);
00083 
00084     // update local coordinates
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         //eSample computes the relative error for this sample
00107         relErr = fabs(dist - rtt) / rtt;
00108     }
00109     // update weighted moving average of local error
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     // estimates the delta factor
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     // show nodes at estimated position TODO
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 }
Generated on Wed May 26 16:21:15 2010 for OverSim by  doxygen 1.6.3