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_UTIL_LQI_DISTANCE_H 00020 #define __ALGORITHMS_LOCALIZATION_DISTANCE_BASED_UTIL_LQI_DISTANCE_H 00021 00022 #include "internal_interface/routing_table/routing_table_static_array.h" 00023 #include "util/pstl/map_static_vector.h" 00024 #include "algorithms/localization/distance_based/util/localization_defutils.h" 00025 00026 00027 //#define DISTANCE_DEBUG_ 00028 00029 namespace wiselib 00030 { 00031 00032 template<typename OsModel_P, typename Debug_P , typename Arithmatic_P, 00033 typename Radio_P = typename OsModel_P::TxRadio, 00034 int TABLE_SIZE = 60 00035 > 00036 class LQIDistanceModel 00037 { 00038 public: 00039 00040 #define LQI_TABLE_SIZE 60 00041 00042 00043 00044 typedef OsModel_P OsModel; 00045 00046 00047 00048 typedef Radio_P Radio; 00049 00050 typedef Debug_P Debug; 00051 00052 00053 00054 typedef typename Radio::node_id_t node_id_t; 00055 typedef typename Radio::block_data_t block_data_t; 00056 typedef typename Radio::size_t size_t; 00057 typedef typename Radio::ExtendedData ExtendedData; 00058 typedef Arithmatic_P Arithmatic; 00059 00060 typedef LQIDistanceModel<OsModel, Debug, Arithmatic, Radio,TABLE_SIZE> self_type; 00061 typedef self_type* self_pointer_t; 00062 00063 //typedef double Arithmatic; 00064 00065 typedef uint8_t lqi_t; 00066 typedef StaticArrayRoutingTable<OsModel, Radio, TABLE_SIZE, Arithmatic> DistanceMap; 00067 typedef MapStaticVector<OsModel_P, lqi_t , Arithmatic, LQI_TABLE_SIZE> LQIMap; 00068 typedef typename DistanceMap::iterator DistanceMapIterator; 00069 typedef typename LQIMap::iterator LQIMapIterator; 00070 // -------------------------------------------------------------------- 00071 enum ErrorCodes 00072 { 00073 SUCCESS = OsModel::SUCCESS, 00074 ERR_UNSPEC = OsModel::ERR_UNSPEC 00075 }; 00076 // -------------------------------------------------------------------- 00077 LQIDistanceModel( ) 00078 00079 { 00080 00081 ready = 0; 00082 } 00083 00084 ~LQIDistanceModel( ) 00085 00086 { 00087 00088 00089 } 00090 // -------------------------------------------------------------------- 00091 int init( Radio* radio, Debug* debug, LQIMap* lqimap) 00092 { 00093 00094 debug_ = debug; 00095 ready = 1; 00096 #ifdef DISTANCE_DEBUG_ 00097 00098 debug_->debug("distance init"); 00099 #endif 00100 radio_ = radio; 00101 radio_->template reg_recv_callback<self_type, &self_type::receive>( this ); 00102 00103 lqis_ = lqimap; 00104 00105 00106 LQIMapIterator previt =lqis_->begin(); 00107 #ifdef DISTANCE_DEBUG_ 00108 for ( LQIMapIterator it = lqis_->begin(); it != lqis_->end(); ++it ) 00109 { 00110 00111 00112 debug_->debug(" lqis is %d %f\n",it->first,it->second); 00113 } 00114 #endif 00115 return SUCCESS; 00116 } 00117 // -------------------------------------------------------------------- 00118 Arithmatic distance( node_id_t to ) 00119 { 00120 00121 00122 if(ready == 0){ 00123 #ifdef DISTANCE_DEBUG_ 00124 debug_->debug(" distance to ::not init "); 00125 #endif 00126 00127 return -1; 00128 00129 }; 00130 00131 // const double UNKNOWN_DISTANCE = DBL_MIN; 00132 Arithmatic distance = -1; 00133 00134 // Arithmatic distance = 250; 00135 00136 #ifdef DISTANCE_DEBUG_ 00137 for ( DistanceMapIterator it2 = distances_.begin(); it2 != distances_.end(); ++it2 ) 00138 { 00139 00140 00141 debug_->debug(" distancess is %x %f\n",it2->first,it2->second); 00142 } 00143 #endif 00144 #ifdef DISTANCE_DEBUG_ 00145 // debug_->debug(" distancess size is %d\n",distances_.size()); 00146 #endif 00147 DistanceMapIterator it = distances_.find( to ); 00148 00149 00150 00151 00152 #ifdef DISTANCE_DEBUG_ 00153 debug_->debug("distance found %f oder %f ",it->second ,distances_[to]); 00154 #endif 00155 00156 if ( (it != distances_.end()) /*&& (it->second!=0)*/){ 00157 distance = it->second; 00158 #ifdef DISTANCE_DEBUG_ 00159 00160 debug_->debug("distance found %f from %x to %x",distance,radio_->id(), to); 00161 #endif 00162 } 00163 00164 return distance; 00165 }; 00166 00167 00168 00169 00170 private: 00171 00172 00173 00174 void receive( node_id_t id, size_t len, block_data_t* data, const ExtendedData& exdata) 00175 { 00176 // TODO: Why does the lqi-radio returns (255 - lqi)? hence, we transform it back here... 00177 lqi_t lqi = 255 - exdata.link_metric(); 00178 00179 if(ready == 0){ 00180 //#ifdef DISTANCE_DEBUG_ 00181 // debug_->debug("receive ::not init "); 00182 //#endif 00183 00184 return; 00185 00186 }; 00187 00188 ready = 0; 00189 00190 if(lqi > 160) 00191 lqi = 151; 00192 00193 if(lqi < 5) 00194 lqi = 5; 00195 00196 #ifdef DISTANCE_DEBUG_ 00197 00198 debug_->debug(" lqi = %d",lqi); 00199 #endif 00200 00201 Arithmatic distance = -1; 00202 00203 LQIMapIterator previt =lqis_->begin(); 00204 00205 // debug_->debug(" begin value %d %f ",previt->first,previt->second); 00206 00207 for (LQIMapIterator it = lqis_->begin(); it != lqis_->end(); ++it ) 00208 { 00209 00210 if ( it->first <= lqi ){ 00211 //distance = it->second + previt->second; 00212 //distances_[id] = distance/2; 00213 00214 00215 if(previt->first == it->first) 00216 distances_[id]=it->second; 00217 else 00218 distances_[id] = previt->second + ( ((it->second - previt->second)/(previt->first - it->first)) * (previt->first - lqi)); 00219 00220 00221 #ifdef DISTANCE_DEBUG_ 00222 00223 debug_->debug(" lqi found = %d = distance %f between %x from %x",lqi,distances_[id],radio_->id(),id); 00224 00225 #endif 00226 ready = 1; 00227 return; 00228 } 00229 00230 previt = it; 00231 //#ifdef DISTANCE_DEBUG_ 00232 00233 // debug_->debug(" lqi is %d %f\n",it->first,it->second); 00234 //#endif 00235 } 00236 00237 00238 #ifdef DISTANCE_DEBUG_ 00239 if(distance == -1) 00240 debug_->debug(" lqi not found \n",lqi,distance); 00241 #endif 00242 00243 00244 //#ifdef DISTANCE_DEBUG_ 00245 00246 // debug_->debug(" distance is %f \n",distances_[id]); 00247 //#endif 00248 00249 00250 // distances_[id] = distance; 00251 #ifdef DISTANCE_DEBUG_ 00252 00253 debug_->debug("distance received %f %f ",distances_[id],distance); 00254 #endif 00255 00256 ready = 1; 00257 00258 } 00259 00260 00261 00262 00263 00264 00265 00266 00267 Radio *radio_; 00268 Debug *debug_; 00269 LQIMap *lqis_; 00270 DistanceMap distances_; 00271 uint8_t ready; 00272 00273 00274 00275 }; 00276 00277 00278 00279 00280 /* template<typename OsModel_P, typename Debug_P , 00281 typename Radio_P = typename OsModel_P::TxRadio, 00282 int TABLE_SIZE = 40> 00283 LQIDistanceModel<OsModel_P, Debug_P >::DistanceMap 00284 LQIDistanceModel<OsModel_P, Debug_P >::distances_ = null; 00285 */ 00286 00287 00288 00289 00290 } 00291 00292 #endif