Wiselib
wiselib.testing/algorithms/localization/triangulation/triangulation.h
Go to the documentation of this file.
00001 #ifndef __TRIANGULATION_H__
00002 #define __TRIANGULATION_H__
00003 
00004 #define DEBUG_TRIANGULATION
00005 
00006 //#include "algorithms/routing/routing_base.h"
00007 #include "algorithms/localization/triangulation/triangulation_message.h"
00008 #include "algorithms/localization/localization_base.h"
00009 #include "util/delegates/delegate.hpp"
00010 //----------------------------------------------------
00011 #include <math.h>
00012 //#include <cmath>
00013 #include <stdlib.h>
00014 #include <time.h>
00015 #include "internal_interface/routing_table/routing_table_static_array.h"
00016 //----------------------------------------------------
00017 int __errno;
00018 //----------------------------------------------------
00019 
00020 namespace wiselib
00021 {
00022 
00027    template<typename OsModel_P,
00028             typename Radio_P,
00029             typename Distance_P,
00030             typename Debug_P = typename OsModel_P::Debug>
00031    class Triangulation
00032 //    : public LocalizationBase<OsModel_P,Radio_P>
00033    {
00034    public:
00035       typedef OsModel_P OsModel;
00036       typedef Radio_P Radio;
00037       typedef Debug_P Debug;
00038       typedef Distance_P Distance;
00039 
00040       typedef StaticArrayRoutingTable <OsModel, Radio, 15, int> int_map_t;
00041       typedef typename int_map_t::iterator int_map_iterator_t;
00042 
00043 
00044       typedef Triangulation<OsModel, Radio, Distance, Debug> self_type;
00045 
00046       typedef typename OsModel::Timer Timer;
00047       typedef typename Timer::millis_t millis_t;
00048 
00049       typedef typename Radio::node_id_t node_id_t;
00050       typedef typename Radio::size_t size_t;
00051       typedef typename Radio::block_data_t block_data_t;
00052       typedef typename Radio::message_id_t message_id_t;
00053 
00054       typedef TriangulationMessage<OsModel, Radio> Message;
00055       // --------------------------------------------------------------------
00056       enum ErrorCodes
00057       {
00058          SUCCESS = OsModel::SUCCESS,
00059          ERR_UNSPEC = OsModel::ERR_UNSPEC,
00060          ERR_NOTIMPL = OsModel::ERR_NOTIMPL
00061       };
00062       // --------------------------------------------------------------------
00065       Triangulation();
00066       ~Triangulation();
00068 
00071       void enable( void );
00072       void disable( void );
00074 
00077       void send(  );
00079 
00082       void receive( node_id_t from, size_t len, block_data_t *data );
00084 
00090       int getIndex(node_id_t);
00091 
00097       int getNode (int);
00098 
00102       void findP();
00103 
00108       void findCoordinatesP();
00109 
00115       void findPQ();
00116 
00122       void findCoordinatesPQ();
00123 
00127       void findCircle();
00128 
00135       int testCircle(int, int);
00136 
00143       void setRating(node_id_t, node_id_t, int);   //Absender-ID, 3. Dreiecks-ID, Bewertung
00144 
00153       void setTriangleGlobal(node_id_t, node_id_t, node_id_t, int);
00154 
00159       bool nodeInTriangles();
00160 
00167       int lookUpTrust(int, int);
00168 
00174       int bestCircleIndex(node_id_t);
00175 
00179       int max(int,int);
00180 
00184       int min(int,int);
00185 
00189       void coordinates_timer_elapsed( void *userdata );
00190 
00194       void complete_triangulation_timer_elapsed( void *userdata);
00195 
00199       void select_best_circle_timer_elapsed( void *userdata);
00200 
00204       void fourth_timer_elapsed( void *userdata);
00205 
00209       void send_timer_elapsed( void *userdata);
00210 
00214       void message_timer_elapsed (void *userdata);
00215 
00216      // void reset_data();
00217 
00218       void triangles_changed(int);
00219 
00220       typedef delegate1<void, int> localization_delegate_t;
00221 
00222       // --------------------------------------------------------------------
00223       template<class T, void (T::*TMethod)(int)>
00224       inline void reg_changed_callback( T *obj_pnt )
00225       {
00226         callback_ = localization_delegate_t::from_method<T, TMethod>( obj_pnt );
00227       };
00228       // --------------------------------------------------------------------
00229       inline void unreg_changed_callback( void )
00230       {
00231         callback_ = localization_delegate_t();
00232       }
00233       // --------------------------------------------------------------------
00234       inline void notify_receivers( int value )
00235       {
00236         if (callback_)
00237            callback_( value );
00238       }
00239 
00240       localization_delegate_t callback_;
00241 
00242       int init( Radio& radio, Timer& timer, Debug& debug )
00243       {
00244          radio_ = &radio;
00245          timer_ = &timer;
00246          debug_ = &debug;
00247          return SUCCESS;
00248       }
00249 
00250       int init()
00251       { return ERR_NOTIMPL; }
00252 
00253       int destruct()
00254       { return ERR_NOTIMPL; }
00255 
00256    private:
00257       Radio& radio()
00258       { return *radio_; }
00259 
00260       Timer& timer()
00261       { return *timer_; }
00262 
00263       Debug& debug()
00264       { return *debug_; }
00265 
00266       typename Radio::self_pointer_t radio_;
00267       typename Timer::self_pointer_t timer_;
00268       typename Debug::self_pointer_t debug_;
00269 
00270       Distance dist_est_;
00271 
00272 
00273       enum MessageIds
00274       {
00275          DISTANCE_CHECK = 1,
00276          DISTANCE_RETURN = 2,
00277          DISTANCE_PROP = 3,
00278          CHECK_CIRCLE = 4,
00279          CHECK_CIRCLE_RETURN = 5,
00280          TRIANGLE_PROP = 6,
00281          ASKFORCIRCLE = 7,
00282          RETURN_CIRCLE = 8,
00283          RESET = 98,
00284          RESET_PROP = 99,
00285 
00286       };
00287 
00288       enum Various
00289       {
00290         MESSAGES_SIZE = 15,
00291         NODECOUNT = 10,
00292         VECTORSIZE = 20,      //1.5*nodecount reicht sicher
00293         MILLIS = 1000,
00294         POSITION_CHANGED = 0,
00295         UNKNOWN_POSITION = 1
00296       };
00297 
00298       short callback_id_;
00299 
00300       struct circle {
00301         node_id_t idFirst, idSecond;
00302         int ratingFirst, ratingSecond;
00303       };
00304       struct triangle {
00305         node_id_t idFirst, idSecond, idThird;
00306         bool prop;
00307         int trust; //1 für: alle stimmen zu, 2 für: einer siehts nicht, 3 für: zwei sehns nicht, 4 für: einer stimmt zu, einer lehnt ab, 5 für: zwei lehnen ab
00308       };
00309 
00310       typedef vector_static<OsModel,triangle,VECTORSIZE> position_t;
00311 
00312       inline position_t *position() {
00313         if(nodeInTriangles)
00314            return &triangles;
00315         else
00316            return NULL;
00317       }
00318 
00319       int_map_t neighbourMap;
00320 
00321       float distances[NODECOUNT];
00322       float ndistances[NODECOUNT][NODECOUNT];
00323       float coordinates[NODECOUNT][2]; //für alle Knoten an [i][0] x und an [i][1] y
00324 
00325       bool send_called;
00326       short neighbourCount;
00327 
00328       int p_index;
00329       int q_index;
00330       node_id_t demandedCircleIDs[3];
00331 
00332       millis_t waitingTime1;
00333       millis_t waitingTime2;
00334       millis_t startupTime;
00335 
00336       bool coordinates_timer_started;
00337       bool send_timer_iteration;
00338       bool coordinates_called;
00339       int send_timer_running;
00340       int complete_triangulation_timer_running;
00341 
00342       vector_static<OsModel, circle, VECTORSIZE> foundCircles;
00343       vector_static<OsModel, triangle, VECTORSIZE> triangles;
00344       vector_static<OsModel, Message, MESSAGES_SIZE> messages;
00345 
00346 
00347    };
00348    // -----------------------------------------------------------------------
00349    // -----------------------------------------------------------------------
00350    // -----------------------------------------------------------------------
00351    template<typename OsModel_P,
00352             typename Radio_P, typename Distance_P,
00353             typename Debug_P>
00354    Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
00355    Triangulation()
00356       : os_           ( 0 ),
00357         callback_id_ ( 0 ),
00358         send_called(false),
00359         coordinates_timer_started(false),
00360         send_timer_iteration(true),
00361         neighbourCount(0),
00362         send_timer_running(0),
00363         complete_triangulation_timer_running(0),
00364         p_index(-1), q_index(-1),
00365         waitingTime1(8000),
00366         waitingTime2(3000),
00367         startupTime (5000)
00368    {};
00369    // -----------------------------------------------------------------------
00370    template<typename OsModel_P,
00371             typename Radio_P, typename Distance_P,
00372             typename Debug_P>
00373    Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
00374    ~Triangulation()
00375    {
00376      // debug().debug(  "Triangulation:dtor\n" );
00377 
00378    };
00379    // -----------------------------------------------------------------------
00380    template<typename OsModel_P,
00381             typename Radio_P, typename Distance_P,
00382             typename Debug_P>
00383    void
00384    Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
00385    enable( void )
00386    {
00387 #ifdef DEBUG_TRIANGULATION
00388       debug().debug(  "Triangulation: Boot for %i - send_timer started \n", radio().id(  ) );
00389 #endif
00390 
00391       radio().enable_radio(  );
00392       callback_id_ = radio().template reg_recv_callback<self_type, &self_type::receive>(  this );
00393 
00394       reg_changed_callback<self_type, &self_type::triangles_changed>(this);
00395 
00396       dist_est_.set_os();
00397       dist_est_.enable();
00398 
00399       neighbourMap[radio().id()] = 0;
00400 
00401       for(int i=0; i<NODECOUNT;i++) {
00402         distances[i] = 0;
00403         coordinates[i][0] = 0;
00404         coordinates[i][1] = 0;
00405         for(int j=0;j<NODECOUNT;j++) {
00406            ndistances[i][j]= 0;
00407         }
00408       }
00409       demandedCircleIDs[2] = -1;
00410 
00411      timer().template set_timer<self_type, &self_type::send_timer_elapsed>( startupTime,this , 0 );
00412 
00413    }
00414 
00415    template<typename OsModel_P,
00416               typename Radio_P, typename Distance_P,
00417               typename Debug_P>
00418      void
00419      Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
00420      disable( void )
00421      {
00422         //debug().debug(  "Triangulation: Disable\n" );
00423 
00424         radio().unreg_recv_callback(  callback_id_ );
00425         radio().disable(  );
00426      }
00427 
00428    // -----------------------------------------------------------------------
00429 
00430      template<typename OsModel_P,
00431            typename Radio_P, typename Distance_P,
00432            typename Debug_P>
00433      void
00434      Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
00435      triangles_changed(int ID) {
00436 
00437        if(ID == POSITION_CHANGED) {
00438           debug().debug("related triangles changed for %i \n", radio().id());
00439        }
00440 
00441      }
00442 
00443      template<typename OsModel_P,
00444           typename Radio_P, typename Distance_P,
00445           typename Debug_P>
00446      int
00447      Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
00448      getIndex(node_id_t nodeID) {
00449 
00450        for(int_map_iterator_t it = neighbourMap.begin(); it != neighbourMap.end(); it++) {
00451           if(it->first == nodeID) {
00452              return it->second;
00453           }
00454        }
00455 
00456        if(neighbourMap.find(nodeID) == neighbourMap.end()) { //nodeID noch nicht gespeichert
00457           neighbourMap[nodeID] = 0;
00458           neighbourMap[nodeID] = neighbourMap.find(nodeID) - neighbourMap.begin();
00459        }
00460 
00461        return neighbourMap.find(nodeID) - neighbourMap.begin();
00462      }
00463 
00464      template<typename OsModel_P,
00465      typename Radio_P, typename Distance_P,
00466      typename Debug_P>
00467      int
00468      Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
00469      getNode(int abc) {
00470 
00471        for(int_map_iterator_t it = neighbourMap.begin(); it != neighbourMap.end(); it++) {
00472           if(it->second == abc) {
00473              return it->first;
00474           }
00475        }
00476        return -1;
00477      }
00478 
00479      template<typename OsModel_P,
00480            typename Radio_P, typename Distance_P,
00481            typename Debug_P>
00482      void
00483      Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
00484      coordinates_timer_elapsed (void* userdata) {
00485 
00486        send_timer_iteration = false;
00487        coordinates_called = true;
00488 
00489       if(p_index==-1 && q_index==-1) {
00490          findP();
00491 
00492          //Distanzen und p/q vorhanden, Kreise schon gesucht?
00493          if(foundCircles.size() == 0) {
00494 
00495             findCircle();
00496 
00497            timer().template set_timer<self_type, &self_type::complete_triangulation_timer_elapsed>( waitingTime1, this, 0 );
00498          }
00499       }
00500      }
00501 
00502 
00503    /* nachsehen, ob man selbst in der Triangulierung drin ist
00504     * wenn nicht: genau 2 nachbarn? -> dreieck einfügen
00505     * wenn sonst: nachricht versenden, nachbarn dreiecke suchen lassen
00506     */
00507    template<typename OsModel_P,
00508                typename Radio_P, typename Distance_P,
00509                typename Debug_P>
00510    void
00511    Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
00512    complete_triangulation_timer_elapsed(void* userdata) {
00513 
00514 #ifdef DEBUG_TRIANGULATION
00515 debug().debug( "complete_triangulation_timer \n");
00516 #endif
00517 
00518         if(!nodeInTriangles()) {
00519 #ifdef DEBUG_TRIANGULATION
00520            debug().debug( "nicht in triangles: %i \n", radio().id());
00521 #endif
00522 
00523            for(int i=0;i<NODECOUNT;i++) {
00524               if(distances[i] != 0) neighbourCount++;
00525            }
00526 
00527            if(neighbourCount == 2) {
00528               int neighbour_indices[2] = {-1,-1};
00529               for(unsigned int i=0; i<neighbourMap.size(); i++) {
00530                  if(distances[i] != 0) {
00531                     if(neighbour_indices[0] == -1) neighbour_indices[0] = i;
00532                     else neighbour_indices[1]=i;
00533                  }
00534               }
00535 
00536               if(getNode(neighbour_indices[0]) < getNode(neighbour_indices[1]))
00537                  setTriangleGlobal(radio().id(),getNode(neighbour_indices[0]),getNode(neighbour_indices[1]),2);
00538               else  setTriangleGlobal(radio().id(),getNode(neighbour_indices[1]),getNode(neighbour_indices[0]),2);
00539 
00540 #ifdef DEBUG_TRIANGULATION
00541               debug().debug( "2 nachbarn, dreieck eingefuegt \n");
00542 #endif
00543            }
00544            else { //nicht genau 2 nachbarn
00545               Message message;
00546               message.set_msg_id(ASKFORCIRCLE);
00547               message.destination = radio().BROADCAST_ADDRESS;
00548               //radio().send(radio().BROADCAST_ADDRESS,message.buffer_size(), (block_data_t*)&message);
00549 
00550               messages.push_back(message);
00551               millis_t random = rand();
00552               random = random % MILLIS;
00553               timer().template set_timer<self_type, &self_type::message_timer_elapsed>( random ,this , 0 );
00554 
00555               demandedCircleIDs[2] = -1;
00556            }
00557 
00558            timer().template set_timer<self_type, &self_type::select_best_circle_timer_elapsed>( waitingTime2, this, 0 );
00559         }
00560 
00561         //*in* triangles, auswertung starten, und doppelte zeit warten (select_best überspringen)
00562         else {
00563            timer().template set_timer<self_type, &self_type::fourth_timer_elapsed>( waitingTime2+waitingTime2, this, 0);
00564         }
00565    }
00566 
00567    /* Auswerten der Ergebnisse von Vorschlägen für Kreise
00568     *
00569     */
00570    template<typename OsModel_P,
00571                   typename Radio_P, typename Distance_P,
00572                   typename Debug_P>
00573    void
00574    Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
00575    select_best_circle_timer_elapsed (void* userdata) {
00576 
00577       //für Auswertung
00578       timer().template set_timer<self_type, &self_type::fourth_timer_elapsed>( waitingTime2, this, 0);
00579 
00580       node_id_t selfID = radio().id();
00581 
00582       //keine Antwort von Nachbarn, dann selbst suchen
00583       if(demandedCircleIDs[2] == -1) {
00584 #ifdef DEBUG_TRIANGULATION
00585         debug().debug( "keine antwort, eigener bestCircle \n");
00586 #endif
00587         int index = bestCircleIndex(selfID);
00588          if(index>=0) {
00589             setTriangleGlobal(selfID,foundCircles[index].idFirst,foundCircles[index].idSecond, lookUpTrust(foundCircles[index].ratingFirst, foundCircles[index].ratingSecond));
00590 
00591 #ifdef DEBUG_TRIANGULATION
00592             debug().debug( "Rating: %i %i \n",foundCircles[index].ratingFirst,foundCircles[index].ratingSecond);
00593             debug().debug( "IDs: %i %i \n", foundCircles[index].idFirst, foundCircles[index].idSecond);
00594 #endif
00595 
00596          }
00597       }
00598       //knoten noch ohne anschluss, hat aber vorschläge erhalten
00599       else if(demandedCircleIDs[2] != -1 && demandedCircleIDs[2] != 0) {
00600 
00601 #ifdef DEBUG_TRIANGULATION
00602          debug().debug( "Kreisvorschlag mit Trust: %i \n", demandedCircleIDs[2]);
00603          debug().debug( "IDs: %i und %i \n", demandedCircleIDs[0],demandedCircleIDs[1]);
00604 #endif
00605 
00606          //prüfen, ob ein eigener kreis besser ist als der vorgeschlagene
00607          int index = bestCircleIndex(selfID);
00608          if(lookUpTrust(foundCircles[index].ratingFirst, foundCircles[index].ratingSecond) < demandedCircleIDs[2])
00609             setTriangleGlobal(selfID,foundCircles[index].idFirst,foundCircles[index].idSecond, lookUpTrust(foundCircles[index].ratingFirst, foundCircles[index].ratingSecond));
00610          else
00611             setTriangleGlobal(selfID,demandedCircleIDs[0],demandedCircleIDs[1],demandedCircleIDs[2]);
00612       }
00613    }
00614 
00615    template<typename OsModel_P,
00616           typename Radio_P, typename Distance_P,
00617           typename Debug_P>
00618    void
00619    Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
00620 	fourth_timer_elapsed (void* userdata) {
00621 
00622 #ifdef DEBUG_TRIANGULATION
00623        debug().debug( "distances-array: \n");
00624        for(int i=0;i<NODECOUNT;i++) {
00625           if(distances[i] != 0) {
00626              debug().debug( "distance[%i]: %i (node %i) \n",i,(int)distances[i],getNode(i));
00627           }
00628        }
00629 
00630        debug().debug( "ndistances: \n");
00631        for(int i=0;i<NODECOUNT;i++) {
00632           for(int j=0; j<NODECOUNT; j++) {
00633              if(ndistances[i][j] != 0) {
00634                 debug().debug( "ndistances[%i][%i]: %i \n", i,j,(int)ndistances[i][j]);
00635              }
00636           }
00637        }
00638 
00639       debug().debug("messages.size()=%i \n", messages.size());
00640 
00641       debug().debug( "foundCircles.size()=%i \n", foundCircles.size());
00642       debug().debug( "triangles.size()=%i \n", triangles.size());
00643 
00644       for(int i=0;i<foundCircles.size();i++) {
00645          debug().debug( "foundCircles[%i].idFirst = %i, idSecond = %i \n",i,foundCircles[i].idFirst, foundCircles[i].idSecond);
00646          debug().debug( "foundCircles[%i].ratingFirst = %i, ratingSecond = %i \n", i, (int)foundCircles[i].ratingFirst, (int)foundCircles[i].ratingSecond);
00647       }
00648 
00649       for(int i=0;i<triangles.size();i++) {
00650          debug().debug( "triangles[%i].idFirst = %i, idSecond = %i,idThird=%i \n",i,triangles[i].idFirst, triangles[i].idSecond, triangles[i].idThird);
00651       }
00652 #endif
00653 
00654    }
00655 
00656    template<typename OsModel_P,
00657    typename Radio_P, typename Distance_P,
00658    typename Debug_P>
00659    void
00660    Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
00661 	message_timer_elapsed (void* userdata) {
00662 
00663       Message message;
00664       message = messages[0];
00665       node_id_t destination = messages[0].destination;
00666       radio().send(destination,message.buffer_size(),(block_data_t*)&message);
00667       debug().debug("msg sent->%i - id:%i \n", (int)destination, (int)messages[0].msg_id());
00668       messages.erase(messages.begin());
00669 
00670    }
00671 
00672 
00673    template<typename OsModel_P,
00674           typename Radio_P, typename Distance_P,
00675           typename Debug_P>
00676    void
00677    Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
00678 	send_timer_elapsed (void* userdata) {
00679 
00680 #ifdef DEBUG_TRIANGULATION
00681       //debug().debug( "send_timer elapsed, rufe send() auf \n");
00682 #endif
00683 
00684       send_timer_running = 0;
00685       if(coordinates_called = true && send_timer_running ==  0) {
00686          timer().template set_timer<self_type, &self_type::send_timer_elapsed>( 500, this, 0);
00687          send_timer_running = 1;
00688       }
00689 
00690       send();
00691    }
00692    // -----------------------------------------------------------------------
00693 
00694    /*template<typename OsModel_P,
00695           typename Radio_P, typename Distance_P,
00696           typename Debug_P>
00697    void Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::reset_data() {
00698 
00699       send_called = false;
00700       p_index = -1;
00701       q_index = -1;
00702       neighbourCount = 0;
00703       neighbourMap.clear();
00704       foundCircles.clear();
00705       triangles.clear();
00706 
00707    }*/
00708 
00709    // -----------------------------------------------------------------------
00710    template<typename OsModel_P,
00711                  typename Radio_P, typename Distance_P,
00712                  typename Debug_P>
00713    int Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::max(int a, int b) {
00714       return (a>b?a:b);
00715    }
00716 
00717    template<typename OsModel_P,
00718                     typename Radio_P, typename Distance_P,
00719                     typename Debug_P>
00720    int Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::min(int a, int b) {
00721       return (a<b?a:b);
00722 
00723    }
00724 
00725    template<typename OsModel_P,
00726               typename Radio_P, typename Distance_P,
00727               typename Debug_P>
00728    void
00729    Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
00730    findP() {
00731 
00732 #ifdef DEBUG_TRIANGULATION
00733          debug().debug( "findP \n");
00734 #endif
00735 
00736       //Sucht einen Knoten, der möglichst viele der eigenen Nachbarn erreicht
00737     int commonNeighbours = 0;
00738     int commonNeighboursBest = 0;
00739     node_id_t nodesID_index = 0;
00740 
00741     //Gehe gesamte Matrix durch
00742     for(int i=0;i<NODECOUNT;i++) {
00743 
00744        //Zwischenspeichern des besten Ergebnisses
00745        if(commonNeighboursBest < commonNeighbours) {
00746           commonNeighboursBest = commonNeighbours;
00747           nodesID_index = i-1;
00748        }
00749 
00750        //Gleichheit der Ergebnisse -> zufällig q tauschen
00751       /* if(commonNeighboursBest == commonNeighbours) {
00752           double random1 = rand()%10;  //random1 von 0..9
00753           if(random1<4) {           //random1 in 0..3 ? Tauschen
00754              nodesID_index = i-1;
00755           }
00756        }*/
00757 
00758        //Zurücksetzen der hilfsvariablen
00759        commonNeighbours = 0;
00760 
00761        if(distances[i] == 0 || i==getIndex(radio().id())) {}         //geprüfter knoten muss nachbar sein
00762        else {
00763           for(int j=0;j<NODECOUNT;j++) {
00764              if(ndistances[i][j] != 0  //geprüfter knoten hat einen nachbarn ..
00765              && distances[j] != 0      //den man auch selber sieht
00766              && i != j              //nachbar des knotens ist er nicht selbst
00767              //&& j !=getIndex(radio().id()))   //nachbar ist man auch nicht selbst
00768              &&j != 0)     //nachbar ist man nicht selber - man steht auf index 0
00769              {
00770                 commonNeighbours++;
00771              } //if
00772           } //for j
00773        } //else
00774     } //for i
00775 
00776     //p setzen, q wählen
00777     //q so wählen, dass q sein gamma in {-1,1} liegt
00778     if(commonNeighboursBest >0 ) {
00779        p_index= nodesID_index;
00780        q_index= -1;
00781        for(int c=0;c<NODECOUNT;c++) {
00782 
00783           //prüfen, ob c als potenzielles q infrage kommt - gamma muss zwischen -1 und 1 sein
00784           float dip = distances[p_index];
00785           float diq = distances[c];
00786           float dpq = ndistances[p_index][c];
00787           double gammaValue = ((diq*diq) + (dip*dip) - (dpq*dpq)) / (2*diq*dip);
00788 
00789           //prüfen, ob Knoten p Knoten c sieht, und ob gamma passt
00790           if(ndistances[p_index][c] != 0 && -1 <= gammaValue && gammaValue <= 1) {
00791              //if(q_index==-1)
00792                 q_index=c;
00793             /* double r = rand() % 10;
00794              if(r<4) q_index=c;*/
00795           }
00796        }
00797     }
00798     else {p_index=-1;q_index=-1;}
00799 
00800    // debug().debug( "p_index: %i->Node %i, q_index: %i->Node %i \n", p_index, getNode(p_index), q_index, getNode(q_index));
00801 
00802     if(p_index!=-1 && q_index!= -1 && coordinates[p_index][1] == 0 && coordinates[q_index][0] == 0 && coordinates[q_index][1] == 0) {
00803           findCoordinatesP();
00804        }
00805 
00806    }
00807 
00808 
00809    template<typename OsModel_P,
00810                     typename Radio_P, typename Distance_P,
00811                     typename Debug_P>
00812    void
00813    Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
00814    findCoordinatesP() {
00815 
00816 #ifdef DEBUG_TRIANGULATION
00817 debug().debug( "findCoordinatesP \n" );
00818 #endif
00819 
00820       int selfIndex = getIndex(radio().id());
00821       coordinates[selfIndex][0] = 0;            //eigenes x: 0
00822       coordinates[selfIndex][1] = 0;            //eigenes y: 0
00823       coordinates[p_index][0] = distances[p_index];      //p: x entspricht abstand
00824       coordinates[p_index][1] = 0;              //p: auf x-achse
00825 
00826       //q-koordinaten
00827    //   double gamma = 0.0;
00828       double dip = distances[p_index];          //distanz i->p
00829       double diq = distances[q_index];          //distanz i->q
00830       double dpq = ndistances[p_index][q_index];         //distanz p->q
00831       double gammaValue = ((diq*diq) + (dip*dip) - (dpq*dpq)) / (2*diq*dip);
00832     //  gamma = acos(gammaValue);
00833     //  coordinates[q_index][0] = diq * (cos(gamma));
00834     //  coordinates[q_index][1] = diq * (sin(gamma));
00835       coordinates[q_index][0] = diq * (gammaValue);               //cos(arccos(x)) = x
00836       coordinates[q_index][1] = diq * sqrt(1-(gammaValue*gammaValue)); //sin(arccos(x)) = sqrt(1-x*x)
00837 
00838       //weitere Knoten
00839      // double alpha = 0.0;
00840 
00841       for(int j=0;j<NODECOUNT;j++) {
00842             if(ndistances[p_index][j] != 0      //p hat j als nachbarn
00843             && distances[j] != 0       //knoten sieht j auch
00844             && j != selfIndex             //j ist man auch nicht selber
00845             && j != p_index               //j ist auch nicht p
00846             && j != q_index)              //und auch nicht q
00847             {
00848              float dij = distances[j];             //distanz i->j
00849              float dpj = ndistances[p_index][j];            //distanz p->j
00850              double alphaValue = ((dij*dij) + (dip*dip) - (dpj*dpj)) / (2*dij*dip);
00851              if(-1 <= alphaValue && alphaValue <= 1) {
00852                // alpha = acos(alphaValue);
00853                // coordinates[j][0] = dij * (cos(alpha));   //x-koordinate von knoten j
00854                 //betrag der y-koordinate von j ...
00855                // coordinates[j][1] = dij * (sin(alpha));
00856 
00857                coordinates[j][0] = dij * alphaValue;
00858                coordinates[j][1] = dij * sqrt(1-(alphaValue*alphaValue));
00859 
00860                 //Distanz von q zu beiden möglichen y-koordinaten: y1 = positiv, y2=negativ
00861 
00862                 double x = (coordinates[q_index][0] - coordinates[j][0])*(coordinates[q_index][0] - coordinates[j][0]); //(x-x0)*(x-x0)
00863                 double y1 =(coordinates[q_index][1] - coordinates[j][1])*(coordinates[q_index][1] - coordinates[j][1]); //(y-y1)*(y-y1)
00864                 double y2 =(coordinates[q_index][1] + coordinates[j][1])*(coordinates[q_index][1] + coordinates[j][1]); //(y-y2)*(y-y2)
00865 
00866                 double dqjCS1 = sqrt(x + y1);   //berechnete Distanz q->j mit j positiv
00867                 double dqjCS2 = sqrt(x + y2);   //berechnete Distanz q->j mit j negativ
00868 
00869                 if(ndistances[q_index][j] != 0) {
00870                    //für schwankende abstände
00871                    double diffPos = fabs(ndistances[q_index][j] - dqjCS1); //Differenzbetrag Messung & Berechnung für j positiv
00872                    double diffNeg = fabs(ndistances[q_index][j] - dqjCS2); //Differenzbetrag Messung & Berechnung für j negativ
00873                    if(diffPos < diffNeg) {}  //j bleibt positiv
00874                    else if(diffPos > diffNeg) {coordinates[j][1] = -(coordinates[j][1]);} //j wird negativ
00875                }
00876                 else {                                   //Distanz q->j gibts nicht, d.h. j ganz weit weg
00877                    if(coordinates[q_index][1] > 0)          //q über der x-Achse ..
00878                       coordinates[j][1] = -(coordinates[j][1]);   //dann ist j drunter
00879                    //else implizit behandelt
00880                 } //else
00881              } // if alpha
00882             } // if knoten hinzufügbar
00883       } // for j
00884 
00885    } //Funktion
00886 
00887    template<typename OsModel_P,
00888                   typename Radio_P, typename Distance_P,
00889                   typename Debug_P>
00890       void
00891       Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
00892       findPQ() {
00893 
00894          int pq[3];  //0: P, 1: Q, 2: Score
00895          pq[2] = 0; pq[1] = -1; pq[0] = -1;
00896          int pqBest[3];
00897          pqBest[2] = 0; pqBest[1] = -1; pqBest[0] = -1;
00898 
00899          for(int i=0; i<NODECOUNT; i++) {
00900 
00901             //beste pq-Kombi speichern
00902             if(pqBest[2] < pq[2]) {
00903                pqBest[0] = pq[0];
00904                pqBest[1] = pq[1];
00905                pqBest[2] = pq[2];
00906             }
00907            /* if(pqBest[2] == pq[2]) {
00908                double random1 = rand()%10;   //random1 von 0..9
00909                if(random1<4) {            //random1 in 0..3 ? Tauschen
00910                   pqBest[0] = pq[0];
00911                   pqBest[1] = pq[1];
00912                   pqBest[2] = pq[2];
00913                }
00914             }*/
00915 
00916 
00917             if(distances[i] != 0 && i!=getIndex(radio().id())) {        // Knoten sieht p
00918                for(int j=0; j<neighbourMap.size(); j++) {
00919                   if(ndistances[i][j] != 0   && distances[j] != 0 && getNode(i)!=getNode(j)) {  //q nachbar von p?, knoten sieht q?, p != q?
00920                            pq[0] = i;           //Setze i=p
00921                            pq[1] = j;           //Setze j=q
00922                            pq[2] = 0;           //Score auf 0
00923 
00924                            //Gamma testen, ob innerhalb (-1,1)
00925                            float dip = distances[i];     //distanz i->p
00926                            float diq = distances[j];     //distanz i->q
00927                            float dpq = ndistances[i][j]; //distanz p->q
00928                            double gammaValue = ((diq*diq) + (dip*dip) - (dpq*dpq)) / (2*diq*dip);
00929 
00930                            if(-1 <= gammaValue && gammaValue <= 1) {
00931                               //jetzt prüfen, wieviele Nachbarn p und q gemein haben
00932                               for(int k=0;k<neighbourMap.size();k++) {
00933                               if(ndistances[pq[0]][k] != 0  //p sieht k
00934                                     && ndistances[pq[1]][k] != 0     //q sieht k
00935                                     && distances[k] != 0          //knoten sieht k auch
00936                                     && pq[0] != k              //p != k
00937                                     && pq[1] != k              //q != k
00938                                     && getIndex(radio().id()) != k)        //k ist nicht der Knoten selbst
00939                               {
00940                                  int scoreTemp = pq[2];
00941                                  scoreTemp++;
00942                                  pq[2] = scoreTemp;
00943                            } //if
00944                               } //for k
00945                            } //if
00946                         } //if
00947                      } // for j
00948                } //if
00949          } // for i
00950 
00951         if(pqBest[2] > 0) {
00952         p_index= pqBest[0];
00953         q_index= pqBest[1];
00954          debug().debug( "p und q gesetzt bei Knoten %i \n", radio().id());
00955 
00956          if(coordinates[p_index][1] == 0 && coordinates[q_index][0] == 0 && coordinates[q_index][1] == 0) {
00957                 findCoordinatesPQ();
00958                 debug().debug("aufruf findCoordinatesPQ bei Knoten %i \n",radio().id());
00959          }
00960 
00961         }
00962 
00963       }  //Funktion
00964 
00965       template<typename OsModel_P,
00966                       typename Radio_P, typename Distance_P,
00967                       typename Debug_P>
00968        void
00969        Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
00970        findCoordinatesPQ() {
00971 
00972          int self = getIndex(radio().id());
00973          coordinates[self][0] = 0;  //eigenes x: 0
00974          coordinates[self][1] = 0;  //eigenes y: 0
00975 
00976          coordinates[p_index][0] = distances[p_index];   //p: x entspricht abstand
00977          coordinates[p_index][1] = 0;           //p: auf x-achse
00978 
00979          //q-koordinaten
00980          double gamma = 0.0;
00981          float dip = distances[p_index];     //distanz i->p
00982          float diq = distances[q_index];     //distanz i->q
00983          float dpq = ndistances[p_index][q_index]; //distanz p->q
00984          double gammaValue = ((diq*diq) + (dip*dip) - (dpq*dpq)) / (2*diq*dip);
00985          gamma = acos(gammaValue);
00986          coordinates[q_index][0] = diq * (cos(gamma));
00987          coordinates[q_index][1] = diq * (sin(gamma));
00988 
00989          //für weitere knoten j:
00990          double alpha = 0.0;
00991          double beta = 0.0;
00992 
00993          for(int j=0;j<NODECOUNT;j++) {
00994             if(ndistances[p_index][j] != 0      //p hat j als nachbarn
00995             && ndistances[q_index][j] != 0      //q auch
00996             && distances[j] != 0       //knoten sieht j auch
00997             && j != self               //j ist man auch nicht selber
00998             && j != p_index               //j ist auch nicht p
00999             && j != q_index)              //und auch nicht q
01000             {
01001                float dij = distances[j];     //distanz i->j
01002                float dpj = ndistances[p_index][j]; //distanz p->j
01003                float dqj = ndistances[q_index][j]; //distanz q->j
01004                double alphaValue = ((dij*dij) + (dip*dip) - (dpj*dpj)) / (2*dij*dip);
01005                double betaValue = ((diq*diq) + (dij*dij) - (dqj*dqj)) / (2*diq*dij);
01006                if(-1 <= betaValue && betaValue <= 1 && -1 <= alphaValue && alphaValue <= 1) {
01007                   alpha = acos(alphaValue);
01008                   beta = acos(betaValue);
01009                   coordinates[j][0] = dij * (cos(alpha));   //x-koordinate von knoten j
01010                   //betrag der y-koordinate von j ...
01011                   coordinates[j][1] = dij * (sin(alpha));
01012                   //über oder unter x-achse? Toleranzbereich:
01013                   double diffGammaAlpha = fabs(alpha-gamma);
01014                  double tolerance = 0.6; //TODO: Toleranzwert
01015                   if( (diffGammaAlpha-tolerance) <= beta && beta <= (diffGammaAlpha+tolerance) ) {}   //beta im tol-bereich von |alpha-gamma| -> y bleibt positiv
01016                      else coordinates[j][1] = -(coordinates[j][1]);                          //sonst: y wird negativ
01017                }
01018             }
01019          }
01020 
01021        } //Funktion
01022 
01023 
01024 
01031    template<typename OsModel_P,
01032                  typename Radio_P, typename Distance_P,
01033                  typename Debug_P>
01034    void
01035    Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
01036    findCircle() {
01037 
01038 #ifdef DEBUG_TRIANGULATION
01039             debug().debug( "findCircle() \n");
01040 #endif
01041 
01042 
01043       for(int i=0;i<NODECOUNT;i++) {                           //Distanz-Array durchgehen
01044          if(distances[i] != 0) {                                  //wenn Nachbar i existiert
01045             for(int j=0; j<neighbourMap.size(); j++) {                  //gehe alle seine Nachbarn durch
01046                if( ndistances[i][j] != 0                          //wenn i einen Nachbarn j hat..
01047                && i != j                                       //und j nicht i ist
01048                && (coordinates[i][0] != 0 || coordinates[i][1] != 0)    //und es zu i Koordinaten gibt
01049                && (coordinates[j][0] != 0 || coordinates[j][1] != 0)    //und zu j auch
01050                )
01051                {
01052                   int testResult = testCircle(i,j);
01053 
01054                   if(testResult == 1) {
01055                      circle c;
01056 
01057                      if(getNode(i) < getNode(j)) {
01058                         c.idFirst = getNode(i);
01059                         c.idSecond = getNode(j);
01060                      }
01061                      else {
01062                         c.idFirst = getNode(j);
01063                         c.idSecond = getNode(i);
01064                      }
01065                      c.ratingFirst = -1;  //-1 kommt bei der Bewertung nicht vor, gibt nur 0,1,2
01066                      c.ratingSecond = -1;
01067 
01068                      for(unsigned int a=0; a<NODECOUNT; a++) {
01069                         if(foundCircles[a].idFirst == min(getNode(i),getNode(j))
01070                         && foundCircles[a].idSecond == max(getNode(i),getNode(j)) ) {
01071                            break;
01072                         }
01073                         else if(a==NODECOUNT-1) {  //gefundener Kreis noch nicht eingetragen
01074                            foundCircles.push_back(c);
01075                             //prüfen lassen, nachricht senden
01076                             Message msg;
01077                             msg.set_msg_id(CHECK_CIRCLE);
01078                             msg.set_node_id(getNode(j));
01079                            //radio().send(getNode(i),msg.buffer_size(),(uint8_t*)&msg);
01080                            // debug().debug("checkcircle->%i \n",(int)getNode(i));
01081 
01082                             msg.destination = getNode(i);
01083                             messages.push_back(msg);
01084                             millis_t random = rand();
01085                             random = random % MILLIS;
01086                             timer().template set_timer<self_type, &self_type::message_timer_elapsed>( 800+random ,this , 0 );
01087 
01088                             msg.set_node_id(getNode(i));
01089 
01090                            // radio().send(getNode(j),msg.buffer_size(),(uint8_t*)&msg);
01091                            // debug().debug( "checkcircle->%i \n", (int)getNode(j));
01092 
01093                             msg.destination = getNode(j);
01094                             messages.push_back(msg);
01095                             random = rand();
01096                             random = random % MILLIS;
01097                             timer().template set_timer<self_type, &self_type::message_timer_elapsed>( random ,this , 0 );
01098                         }
01099                      }
01100                   }
01101                }
01102             }
01103          }
01104       }
01105 
01106    }
01107 
01108 
01115    template<typename OsModel_P,
01116                typename Radio_P, typename Distance_P,
01117                typename Debug_P>
01118    int
01119    Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
01120    testCircle(int B, int C) {
01121       //1 für: Kreis passt, 2 für: Kreis passt nicht, 0 für: Punkte keine Nachbarn
01122 
01123       int self = getIndex(radio().id());
01124       float xA = coordinates[self][0];          //0
01125       float yA = coordinates[self][1];          //0
01126       float xB = 0;
01127       float yB = 0;
01128       float xC = 0;
01129       float yC = 0;
01130       float x1 = 0;
01131       float y1 = 0;
01132       float x2 = 0;
01133       float y2 = 0;
01134       float x3 = 0;
01135       float y3 = 0;
01136 
01137 
01138       if(coordinates[B][0] != 0 || coordinates[B][1] != 0) {   //Prüfen ob Koordinaten vorhanden
01139          xB = coordinates[B][0];
01140          yB = coordinates[B][1];
01141       }
01142       else {
01143          return 0;
01144       }
01145 
01146       if(coordinates[C][0] != 0 || coordinates[C][1] != 0) {   //Prüfen ob Koordinaten vorhanden
01147          xC = coordinates[C][0];
01148          yC = coordinates[C][1];
01149       }
01150       else {
01151             return 0;
01152       }
01153 
01154 
01155       //Schnitt 2er Mittelsenkrechten
01156       int nullCount = 0;
01157       float yAB = yA-yB; if(yAB == 0) nullCount++;
01158       float yAC = yA-yC; if(yAC == 0) nullCount++;
01159       float yBC = yB-yC; if(yBC == 0) nullCount++;
01160 
01161 
01162       if(nullCount >1) {
01163          return 0;
01164 #ifdef DEBUG_TRIANGULATION
01165          debug().debug( "zu oft null \n");
01166 #endif
01167          }  //keine berechnung möglich weil nenner 2 mal 0 - rückgabe 0 oder 2 ?
01168       if(nullCount == 0 || yAC==0) {x1 = xA; y1 = yA; x2 = xB; y2 = yB; x3 = xC; y3= yC;}    //AB & BC
01169       if(yBC==0) {x1 = xC; y1 = yC; x2 = xA; y2 = yA; x3 = xB; y3= yB;}    //AC + AB <=> CA & AB
01170       if(yAB==0) {x1 = xA; y1 = yA; x2 = xC; y2 = yC; x3 = xB; y3= yB;}    //AC + BC <=> AC & CB
01171 
01172 
01173       //Werte für Mittelsenkrechte 1
01174       //y = -(xA-xB)/(yA-yB) * x + xA^2 - xB^2 + yA^2 - yB^2 / 2(yA-yB)
01175       double m1first = (x1-x2) / (y1-y2);
01176       if((y1-y2) == 0){
01177 #ifdef DEBUG_TRIANGULATION
01178          debug().debug( "y1-y2 ist 0; y1 ist %i und y2 ist %i \n",y1,y2);
01179 #endif
01180       }
01181       m1first = (-1) * m1first;
01182       double m1secondZ = (x1*x1) - (x2*x2) + (y1*y1) - (y2*y2);
01183       double m1secondN = 2*(y1-y2);
01184       double m1second = m1secondZ / m1secondN;
01185 
01186       //Werte für Mittelsenkrechte 2
01187       double m2first = (x2-x3)/(y2-y3);
01188       if((y2-y3) == 0) {
01189 #ifdef DEBUG_TRIANGULATION
01190          debug().debug( "y2-y3 ist 0; y2 ist %i und y3 ist %i \n",y2,y3);
01191 #endif
01192       }
01193       m2first = (-1) * m2first;
01194       double m2secondZ = (x2*x2) - (x3*x3) + (y2*y2) - (y3*y3);
01195       double m2secondN = 2*(y2-y3);
01196       double m2second = m2secondZ / m2secondN;
01197 
01198       //Kreismitte mit x und y
01199       double m1fmm2f = m1first - m2first;    //m1-m2
01200       if(m1fmm2f == 0) {}
01201       double m2smm1s = m2second - m1second;  //n2-n1
01202       double x = m2smm1s / m1fmm2f;       //x = ...
01203       double y = (m1first * x) + m1second;      //x einsetzen -> y= ...
01204       double r2 = sqrt((x2-x)*(x2-x) + (y2-y)*(y2-y));   //Radius des Kreises = Abstand Ursprung zur Mitte
01205 
01206 
01207       //Prüfen, ob Dealaunay-Dreieck
01208        for(int k=0;k<NODECOUNT;k++) {                                   //alle Nachbarn durchgehen
01209          if((coordinates[k][0] !=0 || coordinates[k][1] != 0)              //Koordinaten für k vorhanden
01210          && k != self                                             //ausschließen aller mitglieder des dreiecks
01211          && k != B
01212          && k != C) {
01213             float testX = coordinates[k][0];
01214             float testY = coordinates[k][1];
01215 
01216             //Abstand zur Kreismitte
01217             double distR = sqrt(((testX-x)*(testX-x)) + ((testY-y)*(testY-y)));        //Distanz zur Kreismitte
01218             if(distR < r2) {
01219                return 2;
01220             }
01221          }
01222       }
01223       return 1;
01224    }
01225 
01226    template<typename OsModel_P,
01227                typename Radio_P, typename Distance_P,
01228                typename Debug_P>
01229    void
01230    Triangulation<OsModel_P,Radio_P, Distance_P, Debug_P>::
01231    setRating(node_id_t fromID, node_id_t thirdID, int rating)
01232    {
01233       int self = (int)getIndex(radio().id());
01234 
01235     //  debug().debug("setRating mit %i,%i,%i \n", (int)fromID,(int)thirdID,(int)rating);
01236      // debug().debug( "setRating \n");
01237 
01238       for(int i=0; i<=(int)foundCircles.size(); i++) {
01239 
01240         // debug().debug( "for-schleife in setRating \n");
01241         // debug().debug( "pruefe, ob %i oder %i zu aufruf passen \n", (int)foundCircles[i].idFirst, (int)foundCircles[i].idSecond);
01242         // debug().debug( "undzwar zu %i und %i \n", min(fromID,thirdID),max(fromID,thirdID));
01243 
01244 
01245          if((int)foundCircles[i].idFirst == min(fromID,thirdID)
01246          && (int)foundCircles[i].idSecond == max(fromID, thirdID))
01247          {
01248 
01249            // debug().debug( "kreis gefunden in setRating \n");
01250 
01251             if((int)fromID == (int)foundCircles[i].idFirst) {
01252                debug().debug( "set ratingFirst \n");
01253                foundCircles[i].ratingFirst = rating;
01254             }
01255             else if((int)fromID == (int)foundCircles[i].idSecond) {
01256                debug().debug( "set ratingSecond \n");
01257                foundCircles[i].ratingSecond = rating;
01258             }
01259 
01260          if(foundCircles[i].ratingFirst == 1
01261          && foundCircles[i].ratingSecond == 1) {
01262             //in globale Triangulierung eintragen
01263            debug().debug("triangleglobal aus setrating: %i %i %i",getNode(self),foundCircles[i].idFirst, foundCircles[i].idSecond);
01264             //setTriangleGlobal((int)getNode(self), (int)foundCircles[i].idFirst, (int)foundCircles[i].idSecond, 1);
01265             setTriangleGlobal(getNode(self),foundCircles[i].idFirst, foundCircles[i].idSecond, 1);
01266             break;
01267          }
01268          if((foundCircles[i].ratingFirst == 1 && foundCircles[i].ratingSecond == 0)    // einer stimmt zu, der andere sieht zuwenig
01269          || (foundCircles[i].ratingFirst == 0 && foundCircles[i].ratingSecond == 1))      // und umgedreht
01270          {
01271             debug().debug("1 1 0 \n");
01272             setTriangleGlobal((int)getNode(self), (int)foundCircles[i].idFirst, (int)foundCircles[i].idSecond, 2);
01273             break;
01274          }
01275       }
01276    }
01277    }
01278 
01279    template<typename OsModel_P,
01280                   typename Radio_P, typename Distance_P,
01281                   typename Debug_P>
01282    void
01283    Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
01284    setTriangleGlobal(node_id_t a, node_id_t b, node_id_t c, int trust) {
01285 
01287 
01288       //debug().debug("triangleglobal mit %i, %i, %i \n", a,b,c);
01289 
01290       triangle t;
01291       t.trust = trust;
01292 
01293       if(a<b) {
01294          t.idFirst = a;
01295          t.idSecond = b;
01296          t.idThird = c;
01297       }
01298       else if(b < a && a < c) {
01299          t.idFirst = b;
01300          t.idSecond = a;
01301          t.idThird = c;
01302       }
01303       else {
01304          t.idFirst = b;
01305          t.idSecond = c;
01306          t.idThird = a;
01307       }
01308 
01309 
01310       //hinzufügen des dreiecks, falls noch nicht im vector enthalten
01311       //weitergeben der meldung an die nachbarn
01312       for(int i=0; i<VECTORSIZE; i++) {
01313          if(triangles[i].idFirst == a && triangles[i].idSecond == b && triangles[i].idThird == c) {   //Dreieck enthalten?
01314             if(triangles[i].prop != true) {                                            //noch nicht propagiert?
01315                Message message;                                                     //versenden ...
01316                message.set_msg_id(TRIANGLE_PROP);
01317                message.set_node_id(t.idFirst);
01318                message.set_seq_nr(t.idSecond);
01319                message.set_trust(t.trust);
01320                message.set_id(t.idThird);
01321                  // radio().send( radio().BROADCAST_ADDRESS, message.buffer_size(), (block_data_t*)&message);
01322 
01323                message.destination=radio().BROADCAST_ADDRESS;
01324                   messages.push_back(message);
01325                   millis_t random = rand();
01326                   random = random % MILLIS;
01327                   timer().template set_timer<self_type, &self_type::message_timer_elapsed>( random ,this , 0 );
01328 
01329                   triangles[i].prop = true;                                            //als propagiert kennzeichnen
01330             }
01331             break;
01332          }
01333          else if(i==VECTORSIZE-1) {                                                 //Dreieck noch nicht enthalten
01334             t.prop = true;
01335             triangles.push_back(t);                                                 //einfügen und propagieren
01336             Message message;
01337             message.set_msg_id(TRIANGLE_PROP);
01338             message.set_node_id(t.idFirst);
01339             message.set_seq_nr(t.idSecond);
01340             message.set_trust(t.trust);
01341             message.set_id(t.idThird);
01342            // radio().send( radio().BROADCAST_ADDRESS, message.buffer_size(), (block_data_t*)&message);
01343 
01344             message.destination = radio().BROADCAST_ADDRESS;
01345             messages.push_back(message);
01346             millis_t random = rand();
01347             random = random % MILLIS;
01348             timer().template set_timer<self_type, &self_type::message_timer_elapsed>( random ,this , 0 );
01349 
01350 
01351          }
01352       }
01353    }
01354 
01355    template<typename OsModel_P,
01356    typename Radio_P, typename Distance_P,
01357    typename Debug_P>
01358    bool
01359    Triangulation<OsModel_P,Radio_P, Distance_P, Debug_P>::
01360    nodeInTriangles() {
01361       for(unsigned int i=0; i<triangles.size();i++) {
01362          if(radio().id() == triangles[i].idFirst || radio().id() == triangles[i].idSecond || radio().id() == triangles[i].idThird) {
01363             return true;
01364          }
01365       }
01366       return false;
01367    }
01368 
01369    template<typename OsModel_P,
01370    typename Radio_P, typename Distance_P,
01371    typename Debug_P>
01372    int
01373    Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
01374    bestCircleIndex(node_id_t demandedID) {
01375       if(demandedID == radio().id()) {
01376          int bestTrust = 20;
01377          int arrayIndex = -1;
01378          for(unsigned int j=0; j < foundCircles.size(); j++) {
01379             int t = lookUpTrust(foundCircles[j].ratingFirst, foundCircles[j].ratingSecond);
01380             if(t < bestTrust) {
01381                arrayIndex = j;
01382                bestTrust = t;
01383             }
01384          }
01385          return arrayIndex;
01386       }
01387       else {
01388          int bestTrust = 20;
01389          int arrayIndex = -1;
01390          for(unsigned int i=0; i<foundCircles.size();i++) {                               //alle kreise durchgehen
01391             if(demandedID == foundCircles[i].idFirst || demandedID == foundCircles[i].idSecond) {  //einer der knoten ist der gesuchte
01392               int t = lookUpTrust(foundCircles[i].ratingFirst, foundCircles[i].ratingSecond);
01393               if(t < bestTrust) {
01394                  arrayIndex = i;
01395                  bestTrust = t;
01396               }
01397             }
01398          }
01399          return arrayIndex;
01400       }
01401    }
01402 
01403    template<typename OsModel_P,
01404    typename Radio_P, typename Distance_P,
01405    typename Debug_P>
01406    int
01407    Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
01408    lookUpTrust(int ratingFirst, int ratingSecond) {
01409 
01410       //1. 1-1-2 = 3 = gelb
01411       //2. 1-0-0 = 4 = orange
01412       //3. 1-0-2 = 5 = rot
01413       //4. 1-2-2 = 5 = rot
01414 
01415       if((ratingFirst == 1 && ratingSecond == 2) || (ratingFirst == 2 && ratingSecond == 1)) {
01416          return 3;
01417       }
01418       if(ratingFirst == 0 && ratingSecond == 0) {
01419          return 4;
01420       }
01421       if((ratingFirst == 0 && ratingSecond == 2) || (ratingFirst == 2 && ratingSecond == 0)) {
01422          return 5;
01423       }
01424       if(ratingFirst == 2 && ratingSecond == 2) {
01425          return 5;
01426       }
01427       return 5;
01428    }
01429 
01430    template<typename OsModel_P,
01431             typename Radio_P,
01432             typename Distance_P,
01433             typename Debug_P>
01434    void
01435    Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
01436    send()
01437    {
01438      Message msg;
01439 
01440 
01441      // if(!send_called) {
01442 
01443          send_called = true;
01444 
01445          if(send_timer_iteration != false) {
01446             msg.set_msg_id(DISTANCE_CHECK);
01447             radio().send( radio().BROADCAST_ADDRESS, msg.buffer_size(), (uint8_t*)&msg);
01448          }
01449 
01450 
01451 #ifdef DEBUG_TRIANGULATION
01452       //   debug().debug( "aufruf send \n");
01453 #endif
01454 
01455          //timer aufrufen - wenn fertig, p und q suchen - bedingung: distanzen vollständig
01456           if(coordinates_timer_started == false) {
01457              timer().template set_timer<self_type, &self_type::coordinates_timer_elapsed>( waitingTime1, this, 0 );
01458              coordinates_timer_started = true;
01459           }
01460      // }
01461 
01462    }
01463 
01464 
01465 
01466    // -----------------------------------------------------------------------
01467    template<typename OsModel_P,
01468             typename Radio_P, typename Distance_P,
01469             typename Debug_P>
01470    void
01471    Triangulation<OsModel_P, Radio_P, Distance_P, Debug_P>::
01472    receive( node_id_t from, size_t len, block_data_t *data )
01473    {
01474 
01475       if ( from == radio().id() )
01476          return;
01477 
01478 #ifdef DEBUG_TRIANGULATION
01479      debug().debug("msg<-%i \n",(int)from);
01480 #endif
01481 
01482       double distance = dist_est_.distance(from);
01483       //double distance = 3;
01484 
01485       Message* msgrec = (Message*) data;
01486       message_id_t msgID = msgrec->msg_id();
01487 
01488       //Distanz-Anfrage; sendet die Distanz an den anfragenden Knoten zurück
01489       if(msgID == DISTANCE_CHECK && send_timer_iteration != false) {
01490 
01491 #ifdef DEBUG_TRIANGULATION
01492        debug().debug( "distance: %i \n",(int)distance);
01493 #endif
01494 
01495         //Aufruf der Send-Methode, um den Knoten vor dem Timer zu "aktivieren" und die Timer relativ synchron zu starten
01496         if(send_called == false) send();
01497 
01498         if(distance>0) {
01499         Message message;
01500           message.set_msg_id(DISTANCE_RETURN);
01501           message.set_distance(distance);
01502           radio().send(from,message.buffer_size(),(block_data_t*)&message);
01503         }
01504 
01505         if(distances[getIndex(from)] == 0 && distance > 0) {
01506            distances[getIndex(from)] = (float) distance; //Eintragen des Abstands
01507          //  debug().debug( "distances zu %i war leer, beschrieben eben \n", from);
01508         }
01509           else if(distance > 0){
01510            distances[getIndex(from)] = ((float)distance + distances[getIndex(from)]) / 2;
01511            //debug().debug( "distances zu %i war schon beschrieben, neuer wert: %i", from, (int) distances[getIndex(from)]);
01512            //den Mittelwert versenden
01513            Message message;
01514            message.set_msg_id(DISTANCE_PROP);
01515            message.set_distance(distances[getIndex(from)]);
01516            message.set_node_id(from);
01517            radio().send(radio().BROADCAST_ADDRESS,len,(block_data_t*)&message);
01518           }
01519 
01520       }
01521 
01522       //Antwort auf eine Distanzanfrage, in Array speichern
01523       else if(msgID == DISTANCE_RETURN && send_timer_iteration != false) {
01524 
01525         double d = msgrec->distance();
01526 
01527 #ifdef DEBUG_TRIANGULATION
01528       //  debug().debug( "node %i erhaelt distanz zurueck: %i ", radio().id(), (int)d);
01529 #endif
01530 
01531         //Mittelwert aus eigener Messung (distances[from]) und der Messung d des Nachbarn
01532         if(distances[getIndex(from)] == 0) {
01533            distances[getIndex(from)] = d;
01534           // debug().debug( "distances zu %i war leer, beschrieben eben \n", from);
01535            }
01536         else {
01537            distances[getIndex(from)] = (d + distances[getIndex(from)]) / 2;
01538          //  debug().debug( "distances zu %i war schon beschrieben, neuer wert: %i", from, (int) distances[getIndex(from)]);
01539 
01540 
01541         //den Mittelwert versenden
01542         Message message;
01543         message.set_msg_id(DISTANCE_PROP);
01544         message.set_node_id(from);
01545         message.set_distance(distances[getIndex(from)]);
01546         radio().send(radio().BROADCAST_ADDRESS,len,(block_data_t*)&message);
01547         }
01548       }
01549 
01550 
01551       //Verbreiten der Distanzmessung, in Gesamt-Array speichern
01552       else if(msgID == DISTANCE_PROP && send_timer_iteration != false) {
01553 
01554       //  debug().debug( "prop erhalten von %i \n", from);
01555 
01556         node_id_t nodeID = msgrec->node_id();
01557         ndistances[getIndex(from)][getIndex(nodeID)]= msgrec->distance();
01558       }
01559 
01560       //anforderung, einen kreis zu prüfen, mit absender und in node_id enthaltenen Knoten
01561       else if(msgID == CHECK_CIRCLE) {
01562 
01563         Message message;
01564 
01565         node_id_t nodeID = msgrec->node_id();
01566 
01567        // debug().debug( "check_circle von %i, kreis testen mit %i \n", (int)from, (int)nodeID);
01568        // debug().debug( "hole Index von nodeID: %i und von from: %i", (int)getIndex(nodeID), (int)getIndex(from));
01569 
01570         int testResult = testCircle(getIndex(nodeID),getIndex(from));
01571 
01572         message.set_node_id(nodeID);
01573         message.set_msg_id(CHECK_CIRCLE_RETURN);
01574         message.set_result(testResult);
01575 
01576         message.destination = from;
01577         messages.push_back(message);
01578         millis_t random = rand();
01579         random = random % MILLIS;
01580         timer().template set_timer<self_type, &self_type::message_timer_elapsed>( random ,this , 0 );
01581 
01582        // radio().send( from,message.buffer_size(), (block_data_t*)&message);
01583        // debug().debug( "result->%i \n", (int)from);
01584       }
01585 
01586       else if(msgID == CHECK_CIRCLE_RETURN) {
01587 
01588         int result = msgrec->result();
01589         node_id_t nodeID = msgrec->node_id();
01590            debug().debug( "received return<-%i", (int)from);
01591         setRating(from, nodeID, result);
01592       }
01593 
01594       else if(msgID == TRIANGLE_PROP) {
01595         node_id_t a = msgrec->node_id();
01596         node_id_t b = msgrec->seq_nr();
01597       //  int c = atoi((char*)msgrec->payload());
01598         node_id_t c = msgrec->id();
01599         int t = msgrec->trust();
01600         debug().debug("triangle_prop: %i %i %i \n",a,b,c);
01601         setTriangleGlobal(a,b,c,t);
01602       }
01603 
01604       else if(msgID == ASKFORCIRCLE) {
01605         int circleIndex = bestCircleIndex(from);
01606         if (circleIndex>-1) {
01607            Message message;
01608            message.set_msg_id(RETURN_CIRCLE);
01609            if(from != foundCircles[circleIndex].idFirst)
01610                message.set_node_id(foundCircles[circleIndex].idFirst);
01611            else message.set_node_id(foundCircles[circleIndex].idSecond);
01612            message.set_trust(lookUpTrust(foundCircles[circleIndex].ratingFirst,foundCircles[circleIndex].ratingSecond));
01613           //radio().send(from,message.buffer_size(),(block_data_t*)&message);
01614 
01615            messages.push_back(message);
01616            millis_t random = rand();
01617            random = random % MILLIS;
01618            timer().template set_timer<self_type, &self_type::message_timer_elapsed>( random ,this , 0 );
01619         }
01620       }
01621 
01622       else if(msgID == RETURN_CIRCLE) {
01623 
01624         //falls noch keinen kreisvorschlag erhalten oder ein neuer kreisvorschlag ist besser als der alte ...
01625         if(demandedCircleIDs[2] == -1 || demandedCircleIDs[2] > msgrec->trust()) {
01626           if(from < msgrec->node_id()) {
01627              demandedCircleIDs[0] = from;
01628              demandedCircleIDs[1] = msgrec->node_id();
01629           }
01630           else {
01631              demandedCircleIDs[0] = msgrec->node_id();
01632              demandedCircleIDs[1] = from;
01633           }
01634           demandedCircleIDs[2] = msgrec->trust();
01635         }
01636 
01637       }
01638 
01639    }
01640 
01641 }
01642 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines