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