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 __GREEDYLOC_H__ 00020 #define __GREEDYLOC_H__ 00021 00022 #include "algorithms/localization/localization_base.h" 00023 00024 #include "algorithms/localization/greedyloc/greedyloc_message.h" 00025 00026 #include <string.h> 00027 00028 #include "geometry.h" 00029 00030 namespace wiselib 00031 { 00032 00033 template<typename OsModel_P, 00034 typename Node_P, 00035 typename Timer_P = typename OsModel_P::Timer, 00036 typename Radio_P = typename OsModel_P::Radio, 00037 typename Debug_P = typename OsModel_P::Debug> 00038 class Greedyloc 00039 : public LocalizationBase<OsModel_P, Radio_P> 00040 00041 { 00042 public: 00043 typedef OsModel_P OsModel; 00044 typedef Radio_P Radio; 00045 typedef Debug_P Debug; 00046 typedef Node_P Node; 00047 typedef typename Node::NodePosition NodePosition; 00048 typedef NodePosition position_t; 00049 typedef typename Node::NodePosition::Float Float; 00050 typedef Timer_P Timer; 00051 typedef Greedyloc<OsModel, Node, Timer, Radio, Debug> self_type; 00052 typedef typename Radio::node_id_t node_id_t; 00053 typedef typename Radio::size_t size_t; 00054 typedef typename Radio::block_data_t block_data_t; 00055 typedef typename Radio::message_id_t message_id_t; 00056 typedef typename Radio::ExtendedData ExtendedData; 00057 typedef Greedyloc_Message<OsModel, Node, Radio> Message; 00058 00059 Greedyloc(); 00060 ~Greedyloc(); 00061 00062 void enable( void ); 00063 void disable( void ); 00064 00065 position_t position( ){ 00066 if (anchor_flag == 1) 00067 { 00068 return self.position; 00069 } 00070 return NULL; 00071 } 00072 00073 void send( node_id_t receiver, size_t len, block_data_t *data, message_id_t msg_id, Node n ); 00074 00075 void send_greedyloc_msg( void* userdata ); 00076 00077 void receive( node_id_t from, size_t len, block_data_t *data, ExtendedData const &ext ); 00078 00079 Node self; 00080 Node anchor1; 00081 Node anchor2; 00082 Node anchor3; 00083 Float R1; 00084 Float R2; 00085 Float R3; 00086 uint8_t anchor_flag; 00087 00088 void init( Radio& radio, Timer& timer, Debug& debug ) { 00089 radio_ = &radio; 00090 timer_ = &timer; 00091 debug_ = &debug; 00092 } 00093 00094 void destruct() { 00095 } 00096 00097 private: 00098 Radio& radio() 00099 { return *radio_; } 00100 00101 Timer& timer() 00102 { return *timer_; } 00103 00104 Debug& debug() 00105 { return *debug_; } 00106 00107 Radio * radio_; 00108 Timer * timer_; 00109 Debug * debug_; 00110 00111 enum MessageIds 00112 { 00113 GREEDYLOC_MSG_ID 00114 }; 00115 00116 int callback_id_; 00117 }; 00118 template<typename OsModel_P, 00119 typename Node_P, 00120 typename Timer_P, 00121 typename Radio_P, 00122 typename Debug_P> 00123 Greedyloc<OsModel_P, Node_P, Timer_P, Radio_P, Debug_P>:: 00124 Greedyloc( ) 00125 : 00126 R1 (-1 ), 00127 R2 ( -1 ), 00128 R3 ( -1 ), 00129 callback_id_ ( 0 ) 00130 00131 {} 00132 // ----------------------------------------------------------------------- 00133 template<typename OsModel_P, 00134 typename Node_P, 00135 typename Timer_P, 00136 typename Radio_P, 00137 typename Debug_P> 00138 Greedyloc<OsModel_P, Node_P, Timer_P, Radio_P, Debug_P>:: 00139 ~Greedyloc() 00140 {} 00141 // ----------------------------------------------------------------------- 00142 template<typename OsModel_P, 00143 typename Node_P, 00144 typename Timer_P, 00145 typename Radio_P, 00146 typename Debug_P> 00147 void 00148 Greedyloc<OsModel_P, Node_P, Timer_P, Radio_P, Debug_P>:: 00149 enable( void ) 00150 { 00151 radio().enable_radio( ); 00152 self.id = radio().id( ); 00153 debug().debug( "Greedyloc %i: Boot \n", self.id ); 00154 callback_id_ = radio().template reg_recv_callback<self_type, &self_type::receive>( this ); 00155 timer().template set_timer<self_type, &self_type::send_greedyloc_msg>( 10000, this, 0 ); 00156 } 00157 // ----------------------------------------------------------------------- 00158 template<typename OsModel_P, 00159 typename Node_P, 00160 typename Timer_P, 00161 typename Radio_P, 00162 typename Debug_P> 00163 void 00164 Greedyloc<OsModel_P, Node_P, Timer_P, Radio_P, Debug_P>:: 00165 disable( void ) 00166 { 00167 debug().debug( "Greedyloc %i: Disable \n", self.id ); 00168 radio().unreg_recv_callback( callback_id_ ); 00169 radio().disable( ); 00170 } 00171 // ----------------------------------------------------------------------- 00172 template<typename OsModel_P, 00173 typename Node_P, 00174 typename Timer_P, 00175 typename Radio_P, 00176 typename Debug_P> 00177 void 00178 Greedyloc<OsModel_P, Node_P, Timer_P, Radio_P, Debug_P>:: 00179 send( node_id_t destination, size_t len, block_data_t *data, message_id_t msg_id, Node n ) 00180 { 00181 debug().debug( "Greedyloc %i : Send\n", self.id ); 00182 Message message; 00183 message.set_msg_id( msg_id ); 00184 message.set_node( n ); 00185 message.set_payload( len, data ); 00186 debug().debug( "--- msg_id = %i, id = %i, position = ( %i, %i, %i ) \n", message.msg_id(), message.node().id, message.node().position.x, message.node().position.y, message.node().position.z ); 00187 radio().send( destination, message.buffer_size(), (block_data_t*)&message ); 00188 } 00189 // ----------------------------------------------------------------------- 00190 template<typename OsModel_P, 00191 typename Node_P, 00192 typename Timer_P, 00193 typename Radio_P, 00194 typename Debug_P> 00195 void 00196 Greedyloc<OsModel_P, Node_P, Timer_P, Radio_P, Debug_P>:: 00197 receive( node_id_t from, size_t len, block_data_t *data,ExtendedData const &ext ) 00198 { 00199 if (anchor_flag == 0) 00200 { 00201 Message* message = (Message*)data; 00202 if ( message->msg_id() == GREEDYLOC_MSG_ID ) 00203 { 00204 if ( (R1 < 0) && ( R2 < 0 ) && ( R3 < 0 ) ) 00205 { 00206 debug().debug( "Greedyloc %i : Received first anchor message from %i\n", self.id, from ); 00207 anchor1 = message->node(); 00208 R1 = ext.link_metric(); 00209 } 00210 else if ( (R1 >= 0) && ( R2 < 0 ) && ( R3 < 0 ) && ( anchor1.id != from) ) 00211 { 00212 debug().debug( "Greedyloc %i : Received second anchor message from %i\n", self.id, from ); 00213 anchor2 = message->node(); 00214 R2 = ext.link_metric(); 00215 } 00216 else if ( (R1 >= 0) && ( R2 >= 0 ) && ( R3 < 0 ) && (anchor1.id != from) && (anchor2.id != from) ) 00217 { 00218 debug().debug( "Greedyloc %i : Received third anchor message from %i\n", self.id, from ); 00219 anchor3 = message->node(); 00220 R3 = ext.link_metric(); 00221 Geometry <NodePosition>GM; 00222 self.position = GM.trilateration(anchor1.position.x, anchor1.position.y, R1, anchor2.position.x, anchor3.position.y, R2, anchor3.position.x, anchor3.position.y, R3); 00223 anchor_flag = 1; 00224 } 00225 } 00226 } 00227 } 00228 // ----------------------------------------------------------------------- 00229 template<typename OsModel_P, 00230 typename Node_P, 00231 typename Timer_P, 00232 typename Radio_P, 00233 typename Debug_P> 00234 void 00235 Greedyloc<OsModel_P, Node_P, Timer_P, Radio_P, Debug_P>:: 00236 send_greedyloc_msg( void* userdata ) 00237 { 00238 if (anchor_flag == 1) 00239 { 00240 send( radio().BROADCAST_ADDRESS,0, NULL, GREEDYLOC_MSG_ID, self ); 00241 } 00242 timer().template set_timer<self_type, &self_type::send_greedyloc_msg>( 10000, this, 0 ); 00243 } 00244 } 00245 #endif