Wiselib
wiselib.testing/algorithms/localization/distance_based/modules/refinement/localization_iter_lateration_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_ITER_LATERATION_MODULE_H
00020 #define __ALGORITHMS_LOCALIZATION_DISTANCE_BASED_LOCALIZATION_ITER_LATERATION_MODULE_H
00021 
00022 #include "algorithms/localization/distance_based/modules/localization_module.h"
00023 #include "algorithms/localization/distance_based/modules/refinement/localization_iter_lateration_messages.h"
00024 #include "algorithms/localization/distance_based/util/localization_defutils.h"
00025 
00026 namespace wiselib
00027 {
00028 
00030 
00074    template<typename OsModel_P,
00075             typename Radio_P,
00076             typename Distance_P,
00077             typename Debug_P,
00078             typename SharedData_P>
00079    class LocalizationIterLaterationModule
00080       : public LocalizationModule<OsModel_P, Radio_P, SharedData_P>
00081    {
00082 
00083    public:
00084       typedef OsModel_P OsModel;
00085       typedef Radio_P Radio;
00086       typedef Distance_P Distance;
00087       typedef Debug_P Debug;
00088       typedef SharedData_P SharedData;
00089 
00090       typedef LocalizationIterLaterationModule<OsModel, Radio, Distance, Debug, SharedData> self_type;
00091       typedef LocalizationModule<OsModel, Radio, SharedData> base_type;
00092 
00093       typedef typename Radio::size_t size_t;
00094       typedef typename Radio::node_id_t node_id_t;
00095       typedef typename Radio::block_data_t block_data_t;
00096 
00097       typedef LocalizationIterLaterationMessage<OsModel, Radio> IterLaterationMessage;
00098       typedef LocalizationIterLaterationSoundMessage<OsModel, Radio> IterLaterationSoundMessage;
00099 
00100       typedef typename SharedData::NeighborInfoList NeighborInfoList;
00101       typedef typename SharedData::Neighborhood::NeighborhoodIterator NeighborhoodIterator;
00102 
00103       typedef typename SharedData::Neighborhood Neighborhood;
00104 
00108       LocalizationIterLaterationModule();
00110       ~LocalizationIterLaterationModule();
00112 
00113 
00116 
00120       void receive( node_id_t from, size_t len, block_data_t *data );
00127       void work( void );
00129 
00130 
00133 
00136       bool finished( void );
00138 
00139       void rollback( void );
00140 
00141       void init( Radio& radio, Debug& debug, SharedData& shared_data, Distance& distance )
00142       {
00143          radio_ = &radio;
00144          distance_ = &distance;
00145          debug_ = &debug;
00146          this->set_shared_data( shared_data );
00147       }
00148 
00151 
00153       void set_iteration_limit( int iteration_limit )
00154       { iteration_limit_ = iteration_limit; }
00157       void set_min_confident_nbrs( int min_confident_nbrs )
00158       { min_confident_nbrs_ = min_confident_nbrs; }
00162       void set_twin_measure( double twin_measure )
00163       { twin_measure_ = twin_measure; }
00168       void set_abort_pos_update( double abort_pos_update )
00169       { abort_pos_update_ = abort_pos_update; }
00174       void set_res_acceptance( double res_acceptance )
00175       { res_acceptance_ = res_acceptance; }
00177 
00178    protected:
00179 
00182 
00187       bool process_iter_lateration_sound_message( node_id_t from, size_t len, block_data_t *data );
00193       bool process_iter_lateration_message( node_id_t from, size_t len, block_data_t *data );
00195 
00196 
00199 
00202       void iter_lateration_step( void );
00204 
00205 
00206    private:
00207 
00208       enum MessageIds
00209       {
00210          ITER_LATERATION_MESSAGE = 209,
00211          ITER_LATERATION_SOUND_MESSAGE = 210
00212       };
00213 
00214       enum IterLaterationState
00215       {
00216          il_init,
00217          il_work,
00218          il_finished
00219       };
00220 
00221       IterLaterationState state_;
00222       int iteration_limit_;
00223       int iteration_cnt_;
00224       int min_confident_nbrs_;
00225       double twin_measure_;
00226       double abort_pos_update_;
00227       double res_acceptance_;
00228       bool sound_;
00229       Distance* distance_;
00230       Radio* radio_;
00231       Debug* debug_;
00232    };
00233    // ----------------------------------------------------------------------
00234    // ----------------------------------------------------------------------
00235    // ----------------------------------------------------------------------
00236    template<typename OsModel_P,
00237             typename Radio_P,
00238             typename Distance_P,
00239             typename Debug_P,
00240             typename SharedData_P>
00241    LocalizationIterLaterationModule<OsModel_P, Radio_P, Distance_P, Debug_P, SharedData_P>::
00242    LocalizationIterLaterationModule()
00243       : state_               ( il_init ),
00244          iteration_limit_    ( 5 ),
00245          iteration_cnt_      ( 0 ),
00246          min_confident_nbrs_ ( 5 ),
00247          twin_measure_       ( 0.1 ),
00248          abort_pos_update_   ( 0.001 ),
00249          res_acceptance_     ( 0.1 ),
00250          sound_              ( false )
00251    {}
00252    // ----------------------------------------------------------------------
00253    template<typename OsModel_P,
00254             typename Radio_P,
00255             typename Distance_P,
00256             typename Debug_P,
00257             typename SharedData_P>
00258    LocalizationIterLaterationModule<OsModel_P, Radio_P, Distance_P, Debug_P, SharedData_P>::
00259    ~LocalizationIterLaterationModule()
00260    {}
00261    // ----------------------------------------------------------------------
00262    template<typename OsModel_P,
00263             typename Radio_P,
00264             typename Distance_P,
00265             typename Debug_P,
00266             typename SharedData_P>
00267    void
00268    LocalizationIterLaterationModule<OsModel_P, Radio_P, Distance_P, Debug_P, SharedData_P>::
00269    receive( node_id_t from, size_t len, block_data_t *data )
00270    {
00271       switch ( data[0] )
00272       {
00273          case ITER_LATERATION_MESSAGE:
00274             process_iter_lateration_message( from, len, data );
00275             break;
00276          case ITER_LATERATION_SOUND_MESSAGE:
00277             process_iter_lateration_sound_message( from, len, data );
00278             break;
00279       }
00280    }
00281    // ----------------------------------------------------------------------
00282    template<typename OsModel_P,
00283             typename Radio_P,
00284             typename Distance_P,
00285             typename Debug_P,
00286             typename SharedData_P>
00287    void
00288    LocalizationIterLaterationModule<OsModel_P, Radio_P, Distance_P, Debug_P, SharedData_P>::
00289    work( void )
00290    {
00291       if ( state_ == il_finished )
00292          return;
00293 
00294       // do initial stuff;
00295       //    if anchor, send 'init-message' and set state to 'finished';
00296       //    if unknown, check whether the node is sound or not. if sound,
00297       //       send messages, if not, clear estimated position.
00298       if ( state_ == il_init )
00299       {
00300          if ( this->shared_data().is_anchor() )
00301          {
00302             IterLaterationMessage message;
00303             message.set_msg_id( ITER_LATERATION_MESSAGE );
00304             message.set_confidence( this->shared_data().confidence() );
00305             radio_->send( Radio::BROADCAST_ADDRESS, message.buffer_size(), (block_data_t*)&message );
00306 
00307             state_ = il_finished;
00308          }
00309          else
00310          {
00311             sound_ = this->neighborhood().is_sound();
00312 
00313             if ( sound_ && this->shared_data().position() != UNKNOWN_POSITION )
00314             {
00315                IterLaterationMessage message;
00316                message.set_msg_id( ITER_LATERATION_MESSAGE );
00317                message.set_confidence( this->shared_data().confidence() );
00318                radio_->send( Radio::BROADCAST_ADDRESS, message.buffer_size(), (block_data_t*)&message );
00319 
00320                IterLaterationSoundMessage sound_message;
00321                sound_message.set_msg_id( ITER_LATERATION_SOUND_MESSAGE );
00322                radio_->send(  Radio::BROADCAST_ADDRESS, sound_message.buffer_size(), (block_data_t*)&sound_message );
00323             }
00324             else
00325             {
00326                this->shared_data().set_confidence( 0.0 );
00327                this->shared_data().set_position( UNKNOWN_POSITION );
00328             }
00329 
00330             state_ = il_work;
00331          }
00332       }
00333 
00334       if ( state_ == il_work )
00335          iter_lateration_step();
00336    }
00337    // ----------------------------------------------------------------------
00338    template<typename OsModel_P,
00339             typename Radio_P,
00340             typename Distance_P,
00341             typename Debug_P,
00342             typename SharedData_P>
00343    bool
00344    LocalizationIterLaterationModule<OsModel_P, Radio_P, Distance_P, Debug_P, SharedData_P>::
00345    process_iter_lateration_sound_message( node_id_t from, size_t len, block_data_t *data )
00346    {
00347       if ( this->shared_data().is_anchor() || state_ == il_finished )
00348          return true;
00349 
00350       this->neighborhood().add_sound( from );
00351 
00352       if ( !sound_ )
00353       {
00354          if ( (sound_ = this->neighborhood().is_sound()) )
00355          {
00356             IterLaterationSoundMessage message;
00357             message.set_msg_id( ITER_LATERATION_SOUND_MESSAGE );
00358             radio_->send(  Radio::BROADCAST_ADDRESS, message.buffer_size(), (block_data_t*)&message );
00359          }
00360       }
00361 
00362       return true;
00363    }
00364    // ----------------------------------------------------------------------
00365    template<typename OsModel_P,
00366             typename Radio_P,
00367             typename Distance_P,
00368             typename Debug_P,
00369             typename SharedData_P>
00370    bool
00371    LocalizationIterLaterationModule<OsModel_P, Radio_P, Distance_P, Debug_P, SharedData_P>::
00372    process_iter_lateration_message( node_id_t from, size_t len, block_data_t *data )
00373    {
00374       if ( this->shared_data().is_anchor() || state_ == il_finished )
00375          return true;
00376 
00377       IterLaterationMessage* msg = (IterLaterationMessage*)data;
00378       double distance = distance_->distance( from );
00379 
00380       this->neighborhood().update_neighbor( from, distance );
00381       NeighborhoodIterator it = this->neighborhood().find( from );
00382       it->second->set_pos( msg->position() );
00383       it->second->set_confidence( msg->confidence() );
00384 
00385       return true;
00386    }
00387    // ----------------------------------------------------------------------
00388    template<typename OsModel_P,
00389             typename Radio_P,
00390             typename Distance_P,
00391             typename Debug_P,
00392             typename SharedData_P>
00393    void
00394    LocalizationIterLaterationModule<OsModel_P, Radio_P, Distance_P, Debug_P, SharedData_P>::
00395    iter_lateration_step( void )
00396    {
00397       if ( state_ == il_finished || !sound_ )
00398          return;
00399 
00400       if ( iteration_cnt_ >= iteration_limit_ )
00401          state_ = il_finished;
00402       ++iteration_cnt_;
00403 
00404       this->neighborhood().reassign_twins( twin_measure_ * this->shared_data().communication_range() );
00405 
00406      if ( this->neighborhood().confident_neighbor_cnt() < min_confident_nbrs_ )
00407          return;
00408 
00409       Vec est_pos;
00410       NeighborInfoList neighbors;
00411       collect_neighbors<OsModel, Neighborhood, NeighborInfoList>( this->neighborhood(), lat_confident, neighbors );
00412 
00413      // try to update position. if lateration fails, confidence is set to 0,
00414       // else position is updated and confidence is set to average of all
00415       // neighbor confidences
00416       if ( est_pos_lateration<OsModel, NeighborInfoList>( neighbors, est_pos, lat_confident, false ) &&
00417             est_pos_lateration<OsModel, NeighborInfoList>( neighbors, est_pos, lat_confident, true ) )
00418       {
00419          this->shared_data().set_confidence( this->neighborhood().avg_neighbor_confidence() );
00420 
00421          // check validity of new position. if check fails, there is a chance
00422          // of 'res_acceptance_', which is normally set to 0.1, to accept
00423          // the position anyway. this is done to avoid being trapped in a
00424          // local minimum. moreover, if the bad position is accepted, the
00425          // confidence is reduced by 50%.
00426          if ( !check_residue<OsModel, NeighborInfoList>( neighbors, est_pos, lat_confident, this->shared_data().communication_range() ) )
00427          {
00428             // TODO: add random variables to Wiselib!
00429 //             if ( res_acceptance_ > uniform_random_0i_1i() )
00430 //                set_confidence( observer().confidence() / 2 );
00431 //             else
00432             {
00433                if ( this->shared_data().confidence() == 0.0 )
00434                   return;
00435                this->shared_data().set_confidence( 0.0 );
00436                this->shared_data().set_position( UNKNOWN_POSITION );
00437 
00438                IterLaterationMessage message;
00439                message.set_msg_id( ITER_LATERATION_MESSAGE );
00440                message.set_confidence( this->shared_data().confidence() );
00441                radio_->send(  Radio::BROADCAST_ADDRESS, message.buffer_size(), (block_data_t*)&message );
00442 
00443                return;
00444             }
00445          }
00446 
00447          // check, whether the new position is very close to the old one or
00448          // not. if so, refinement is finished.
00449          if ( this->shared_data().position() != UNKNOWN_POSITION )
00450          {
00451             double pos_diff = euclidean_distance( est_pos, this->shared_data().position() );
00452 
00453             if ( pos_diff < abort_pos_update_ * this->shared_data().communication_range() )
00454                state_ = il_finished;
00455          }
00456 
00457          this->shared_data().set_position( est_pos );
00458       }
00459       else
00460       {
00461          if ( this->shared_data().confidence() == 0.0 )
00462             return;
00463          this->shared_data().set_confidence( 0.0 );
00464          this->shared_data().set_position( UNKNOWN_POSITION );
00465       }
00466 
00467       IterLaterationMessage message;
00468       message.set_msg_id( ITER_LATERATION_MESSAGE );
00469       message.set_confidence( this->shared_data().confidence() );
00470       radio_->send( Radio::BROADCAST_ADDRESS, message.buffer_size(), (block_data_t*)&message );
00471    }
00472    // ----------------------------------------------------------------------
00473    template<typename OsModel_P,
00474             typename Radio_P,
00475             typename Distance_P,
00476             typename Debug_P,
00477             typename SharedData_P>
00478    bool
00479    LocalizationIterLaterationModule<OsModel_P, Radio_P, Distance_P, Debug_P, SharedData_P>::
00480    finished( void )
00481    {
00482       return state_ == il_finished;
00483    }
00484     // ----------------------------------------------------------------------
00485     template<typename OsModel_P,
00486             typename Radio_P,
00487             typename Distance_P,
00488             typename Debug_P,
00489             typename SharedData_P>
00490    void
00491    LocalizationIterLaterationModule<OsModel_P, Radio_P, Distance_P, Debug_P, SharedData_P>::
00492    rollback( void )
00493    {
00494 #ifdef LOCALIZATION_DISTANCEBASED_ITER_LATERATION_DEBUG
00495       debug_->debug( "iter lateration rollback" );
00496 #endif
00497       state_ = il_init;
00498       iteration_cnt_ = 0;
00499       sound_ = false;
00500    }
00501 
00502 }// namespace wiselib
00503 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines