Wiselib
wiselib.testing/algorithms/localization/distance_based/modules/distance/localization_sum_dist_module.h
Go to the documentation of this file.
00001 /***************************************************************************
00002  ** This file is part of the generic algorithm library Wiselib.           **
00003  ** Copyright (C) 2008,2009 by the Wisebed (www.wisebed.eu) project.      **
00004  **                                                                       **
00005  ** The Wiselib is free software: you can redistribute it and/or modify   **
00006  ** it under the terms of the GNU Lesser General Public License as        **
00007  ** published by the Free Software Foundation, either version 3 of the    **
00008  ** License, or (at your option) any later version.                       **
00009  **                                                                       **
00010  ** The Wiselib is distributed in the hope that it will be useful,        **
00011  ** but WITHOUT ANY WARRANTY; without even the implied warranty of        **
00012  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         **
00013  ** GNU Lesser General Public License for more details.                   **
00014  **                                                                       **
00015  ** You should have received a copy of the GNU Lesser General Public      **
00016  ** License along with the Wiselib.                                       **
00017  ** If not, see <http://www.gnu.org/licenses/>.                           **
00018  ***************************************************************************/
00019 #ifndef __ALGORITHMS_LOCALIZATION_DISTANCE_BASED_LOCALIZATION_SUM_DIST_MODULE_H
00020 #define __ALGORITHMS_LOCALIZATION_DISTANCE_BASED_LOCALIZATION_SUM_DIST_MODULE_H
00021 
00022 #include "algorithms/localization/distance_based/modules/localization_module.h"
00023 #include "algorithms/localization/distance_based/modules/distance/localization_sum_dist_messages.h"
00024 #include "algorithms/localization/distance_based/util/localization_defutils.h"
00025 #include "config_testing.h"
00026 
00027 
00028 namespace wiselib
00029 {
00030 
00032 
00039    template<typename OsModel_P,
00040             typename Radio_P,
00041             typename Clock_P,
00042             typename Distance_P,
00043             typename Debug_P,
00044             typename SharedData_P,
00045             typename Arithmatic_P >
00046    class LocalizationSumDistModule
00047       : public LocalizationModule<OsModel_P, Radio_P, SharedData_P>
00048    {
00049 
00050    public:
00051       typedef OsModel_P OsModel;
00052       typedef Radio_P Radio;
00053       typedef Clock_P Clock;
00054       typedef Distance_P Distance;
00055       typedef Debug_P Debug;
00056       typedef SharedData_P SharedData;
00057       typedef Arithmatic_P Arithmatic;
00058 
00059 
00060       typedef LocalizationSumDistModule<OsModel, Radio, Clock, Distance, Debug, SharedData, Arithmatic> self_type;
00061       typedef LocalizationModule<OsModel, Radio, SharedData> base_type;
00062 
00063       typedef typename Radio::size_t size_t;
00064       typedef typename Radio::node_id_t node_id_t;
00065       typedef typename Radio::block_data_t block_data_t;
00066 
00067       typedef typename Clock_P::time_t time_t;
00068 
00069       typedef LocalizationSumDistMessage<OsModel, Radio, Arithmatic> SumDistMessage;
00070 
00071       typedef typename SharedData::Neighborhood::NeighborhoodIterator NeighborhoodIterator;
00072 
00076       LocalizationSumDistModule();
00077       ~LocalizationSumDistModule();
00079 
00080 
00083 
00087       void receive( node_id_t from, size_t len, block_data_t *data );
00093       void work( void );
00095 
00096 
00099 
00102       bool finished( void );
00104 
00105       void rollback( void );
00106 
00107 
00108       void init( Radio& radio, Clock& clock, Debug& debug, SharedData& shared_data, Distance& distance )
00109       {
00110          radio_ = &radio;
00111          clock_ = &clock;
00112          debug_ = &debug;
00113          this->set_shared_data( shared_data );
00114          distance_ = &distance;
00115 
00116          last_useful_msg_ = clock_->time();
00117 
00118          messages_counter_ = 0;
00119       }
00120 
00121 
00122    protected:
00123 
00126 
00130       bool process_sum_dist_message( node_id_t from, size_t len, block_data_t *data );
00132 
00133 
00134    private:
00135 
00136       enum MessagesIds
00137       {
00138          SUM_DIST_MESSAGE = 203
00139       };
00140 
00141       enum SumDistState
00142       {
00143          sd_init,
00144          sd_work,
00145          sd_finished
00146       };
00147 
00148       SumDistState state_;
00149       time_t last_useful_msg_;
00150       uint8_t messages_counter_;
00151 
00152       Radio* radio_;
00153       Clock* clock_;
00154       Debug* debug_;
00155       Distance* distance_;
00156 
00157    };
00158    // ----------------------------------------------------------------------
00159    // ----------------------------------------------------------------------
00160    // ----------------------------------------------------------------------
00161    template<typename OsModel_P,
00162             typename Radio_P,
00163             typename Clock_P,
00164             typename Distance_P,
00165             typename Debug_P,
00166             typename SharedData_P,
00167             typename Arithmatic_P>
00168    LocalizationSumDistModule<OsModel_P, Radio_P, Clock_P, Distance_P, Debug_P, SharedData_P, Arithmatic_P>::
00169    LocalizationSumDistModule()
00170       : state_( sd_init )
00171    {}
00172    // ----------------------------------------------------------------------
00173    template<typename OsModel_P,
00174             typename Radio_P,
00175             typename Clock_P,
00176             typename Distance_P,
00177             typename Debug_P,
00178             typename SharedData_P,
00179             typename Arithmatic_P>
00180    LocalizationSumDistModule<OsModel_P, Radio_P, Clock_P, Distance_P, Debug_P, SharedData_P, Arithmatic_P>::
00181    ~LocalizationSumDistModule()
00182    {}
00183    // ----------------------------------------------------------------------
00184    template<typename OsModel_P,
00185             typename Radio_P,
00186             typename Clock_P,
00187             typename Distance_P,
00188             typename Debug_P,
00189             typename SharedData_P,
00190             typename Arithmatic_P>
00191    void
00192    LocalizationSumDistModule<OsModel_P, Radio_P, Clock_P, Distance_P, Debug_P, SharedData_P, Arithmatic_P>::
00193    receive( node_id_t from, size_t len, block_data_t *data )
00194    {
00195 
00196 #ifdef LOCALIZATION_DISTANCEBASED_SUMDIST_DEBUG
00197       debug_->debug(  "Message received data[0] = %d from %x \n",
00198                     data[0],from);
00199 #endif
00200 
00201       if ( data[0] == SUM_DIST_MESSAGE )
00202          process_sum_dist_message( from, len, data );
00203    }
00204    // ----------------------------------------------------------------------
00205    template<typename OsModel_P,
00206             typename Radio_P,
00207             typename Clock_P,
00208             typename Distance_P,
00209             typename Debug_P,
00210             typename SharedData_P,
00211             typename Arithmatic_P>
00212    void
00213    LocalizationSumDistModule<OsModel_P, Radio_P, Clock_P, Distance_P, Debug_P, SharedData_P, Arithmatic_P>::
00214    work( void )
00215    {
00216       // do initial stuff;
00217       //    if anchor, send 'init-message' and set state to 'finished';
00218       //    if unknown, start working
00219 
00220 
00221       if ( state_ == sd_init )
00222       {
00223          if ( this->shared_data().is_anchor() )
00224          {
00225             SumDistMessage message;
00226             message.set_msg_id( SUM_DIST_MESSAGE );
00227             message.set_path_length( 0.0 );
00228             message.set_anchor( radio_->id() );
00229             message.set_anchor_position( this->shared_data().position() );
00230 
00231 #ifdef LOCALIZATION_DISTANCEBASED_SUMDIST_DEBUG
00232       debug_->debug(  "Anchor sendet data[0]= %d \n",
00233            ((block_data_t*)&message)[0] );
00234 #endif
00235 
00236 
00237             radio_->send(  Radio::BROADCAST_ADDRESS, message.buffer_size(), (block_data_t*)&message );
00238             messages_counter_++;
00239             if(messages_counter_>5)
00240                state_ = sd_finished;
00241          }
00242          else
00243             state_ = sd_work;
00244       }
00245 
00246       // if given idle-time is passed ( no more useful messages came in ),
00247       // set state to 'finished'
00248       if ( clock_->time() - last_useful_msg_ > this->shared_data().idle_time() ){
00249          state_ = sd_finished;
00250 #ifdef LOCALIZATION_DISTANCEBASED_SUMDIST_DEBUG
00251          int shareddatatime = this->shared_data().idle_time().sec();
00252          time_t def =  clock_->time() - last_useful_msg_;
00253         if(radio_->id()==0x9999)
00254         debug_->debug(  "SUMDIST::finished due to idle time %d  %d \n ",shareddatatime,def.sec());
00255 #endif
00256       }
00257    }
00258    // ----------------------------------------------------------------------
00259    template<typename OsModel_P,
00260             typename Radio_P,
00261             typename Clock_P,
00262             typename Distance_P,
00263             typename Debug_P,
00264             typename SharedData_P,
00265             typename Arithmatic_P>
00266    bool
00267    LocalizationSumDistModule<OsModel_P, Radio_P, Clock_P, Distance_P, Debug_P, SharedData_P, Arithmatic_P>::
00268    process_sum_dist_message( node_id_t from, size_t len, block_data_t* data )
00269    {
00270 
00271 #ifdef LOCALIZATION_DISTANCEBASED_SUMDIST_DEBUG
00272       debug_->debug(  "Process sum dist message state= %d",state_ );
00273 #endif
00274       if ( state_ == sd_finished || this->shared_data().is_anchor() )
00275          return true;
00276 
00277 #ifdef LOCALIZATION_DISTANCEBASED_SUMDIST_DEBUG
00278       debug_->debug(  "state_ != sd_finished || this->shared_data().is_anchor()" );
00279 #endif
00280 
00281       SumDistMessage* msg = (SumDistMessage*)data;
00282       node_id_t anchor = msg->anchor();
00283       Vec<Arithmatic> anchor_pos = msg->anchor_position();
00284       Arithmatic rcvd_path = msg->path_length();
00285 
00286 
00287 
00288       Arithmatic distance = distance_->distance( from );
00289 
00290 #ifdef LOCALIZATION_DISTANCEBASED_SUMDIST_DEBUG
00291       debug_->debug(  "rcvd_path %f distance %f  ",rcvd_path, distance);
00292 #endif
00293 
00294       if ( distance == -1 ){
00295         #ifdef LOCALIZATION_DISTANCEBASED_SUMDIST_DEBUG
00296         if(radio_->id()==0x9999)
00297         debug_->debug(  "unknown dist  ");
00298       #endif
00299          return false;
00300       }
00301          else{
00302           #ifdef LOCALIZATION_DISTANCEBASED_SUMDIST_DEBUG
00303           if(radio_->id()==0x9999)
00304           debug_->debug(  "known dist  ");
00305           #endif
00306          }
00307 
00308       rcvd_path += distance;
00309 
00310 #ifdef LOCALIZATION_DISTANCEBASED_SUMDIST_DEBUG
00311       if(radio_->id()==0x9999)
00312       debug_->debug(  "rcvd_path %f distance after adding %f", rcvd_path, distance);
00313 #endif
00314       // if anchor is new and floodlimit not reached, insert new anchor;
00315       // if anchor is known and new distance is smaller than old one,
00316       //    update info;
00317       // otherwise return
00318       NeighborhoodIterator it = this->neighborhood().find( anchor );
00319       if ( it == this->neighborhood().end_neighborhood() )
00320       {
00321 #ifdef LOCALIZATION_DISTANCEBASED_SUMDIST_DEBUG
00322         if(radio_->id()==0x9999)
00323       debug_->debug(  "SUMDIST::adding anker");
00324 #endif
00325          if ( this->neighborhood().anchor_cnt() >= (int)this->shared_data().floodlimit() )
00326             return true;
00327 
00328          this->neighborhood().update_anchor( anchor, anchor_pos );
00329 #ifdef LOCALIZATION_DISTANCEBASED_SUMDIST_DEBUG
00330         if(radio_->id()==0x9999)
00331       debug_->debug(  "SUMDIST::updateanker %f %f",anchor_pos.x(),anchor_pos.y());
00332 #endif
00333 
00334          // set iterator to the new inserted anchor
00335          it = this->neighborhood().find( anchor );
00336 
00337          it->second.set_distance( rcvd_path );
00338          this->neighborhood().set_ref_node( anchor, from );
00339       }
00340       else
00341       {
00342 #ifdef LOCALIZATION_DISTANCEBASED_SUMDIST_DEBUG
00343          debug_->debug(  "SUMDIST:: not adding anker");
00344 #endif
00345           if ( it->second.distance() <= rcvd_path )
00346              return true;
00347          if ( it->second.distance() > rcvd_path )
00348          {
00349             it->second.set_distance( rcvd_path );
00350             this->neighborhood().set_ref_node( anchor, from );
00351          }
00352       }
00353 
00354       // set time of last useful message to actual and broadcast new info
00355       last_useful_msg_ = clock_->time(  );
00356       SumDistMessage message;
00357       message.set_msg_id( SUM_DIST_MESSAGE );
00358       message.set_anchor( msg->anchor() );
00359       message.set_anchor_position( msg->anchor_position() );
00360       message.set_path_length( it->second.distance() );
00361       radio_->send( Radio::BROADCAST_ADDRESS, message.buffer_size(), (block_data_t*)&message );
00362 
00363 #ifdef LOCALIZATION_DISTANCEBASED_SUMDIST_DEBUG
00364       debug_->debug(  "New or smaller path at %x to %x is %d\n",
00365                     radio_->id(), msg->anchor(), (uint8_t)rcvd_path );
00366 #endif
00367 
00368       return true;
00369    }
00370    // ----------------------------------------------------------------------
00371    template<typename OsModel_P,
00372             typename Radio_P,
00373             typename Clock_P,
00374             typename Distance_P,
00375             typename Debug_P,
00376             typename SharedData_P,
00377             typename Arithmatic_P>
00378    bool
00379    LocalizationSumDistModule<OsModel_P, Radio_P, Clock_P, Distance_P, Debug_P, SharedData_P,Arithmatic_P>::
00380    finished( void )
00381    {
00382       return state_ == sd_finished;
00383    }
00384    // ----------------------------------------------------------------------
00385    template<typename OsModel_P,
00386             typename Radio_P,
00387             typename Clock_P,
00388             typename Distance_P,
00389             typename Debug_P,
00390             typename SharedData_P,
00391             typename Arithmatic_P>
00392    void
00393    LocalizationSumDistModule<OsModel_P, Radio_P, Clock_P, Distance_P, Debug_P, SharedData_P,Arithmatic_P>::
00394    rollback( void )
00395    {
00396       state_ = sd_init;
00397 
00398       last_useful_msg_ = clock_->time();
00399 
00400 
00401       this->shared_data().reset_neighborhood_();
00402 
00403 
00404       messages_counter_ = 0;
00405    }
00406 
00407 }// namespace wiselib
00408 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines