Wiselib
|
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