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 __ANTS_DUTY_CYCLING_ALGORITHM_H__ 00020 #define __ANTS_DUTY_CYCLING_ALGORITHM_H__ 00021 00022 #include "algorithms/energy_preservation/ants_duty_cycling/ants_duty_cycling_message.h" 00023 #include "util/delegates/delegate.hpp" 00024 00025 // TODO: change shawn os()-> calls to wiselib calls 00026 00027 //TODO: REMOVE!!!!!!! 00028 #include "sys/processor.h" 00029 #include "sys/event_scheduler.h" 00030 #include "sys/misc/random/random_variable.h" 00031 #include "sys/misc/random/random_variable_keeper.h" 00032 #include "sys/node.h" 00033 #include "sys/simulation/simulation_controller.h" 00034 #include "sys/simulation/simulation_environment.h" 00035 #include "sys/taggings/basic_tags.h" 00036 #include "sys/tag.h" 00037 #include "sys/comm_models/disk_graph_model.h" 00038 00039 // #define ANTS_DUTY_CYCLING_DEBUG 00040 00041 namespace wiselib 00042 { 00043 00046 template<typename OsModel_P, 00047 typename Radio_P, 00048 typename Timer_P, 00049 typename Clock_P, 00050 typename Debug_P = typename OsModel_P::Debug> 00051 class AntsDutyCyclingAlgorithm 00052 { 00053 public: 00054 typedef OsModel_P OsModel; 00055 typedef Radio_P Radio; 00056 typedef Timer_P Timer; 00057 typedef Clock_P Clock; 00058 typedef Debug_P Debug; 00059 00060 typedef AntsDutyCyclingAlgorithm<OsModel, Radio, Timer, Clock, Debug> self_type; 00061 00062 typedef typename Radio::node_id_t node_id_t; 00063 typedef typename Radio::size_t size_t; 00064 typedef typename Radio::block_data_t block_data_t; 00065 typedef typename Radio::message_id_t message_id_t; 00066 00067 typedef typename Clock::time_t time_t; 00068 00069 typedef AntDutyCyclingMessage<OsModel, Radio> Message; 00070 00071 typedef delegate1<void, int> energy_preservation_delegate_t; 00072 // -------------------------------------------------------------------- 00073 enum ErrorCodes 00074 { 00075 SUCCESS = OsModel::SUCCESS, 00076 ERR_UNSPEC = OsModel::ERR_UNSPEC, 00077 ERR_NOTIMPL = OsModel::ERR_NOTIMPL 00078 }; 00079 // -------------------------------------------------------------------- 00080 enum EnergyPreservationActivity 00081 { 00082 EPA_ACTIVE = 1, 00083 EPA_INACTIVE 00084 }; 00085 // -------------------------------------------------------------------- 00088 AntsDutyCyclingAlgorithm(); 00089 ~AntsDutyCyclingAlgorithm(); 00091 // -------------------------------------------------------------------- 00095 void enable( void ); 00097 void disable( void ); 00098 void set_configuration( void ); 00100 // -------------------------------------------------------------------- 00103 // -------------------------------------------------------------------- 00104 template<class T, void (T::*TMethod)(int)> 00105 inline int reg_changed_callback( T *obj_pnt ) 00106 { 00107 callback_ = energy_preservation_delegate_t::from_method<T, TMethod>( obj_pnt ); 00108 return 0; 00109 } 00110 // -------------------------------------------------------------------- 00111 inline int unreg_changed_callback( int ) 00112 { 00113 callback_ = energy_preservation_delegate_t(); 00114 return SUCCESS; 00115 } 00116 // -------------------------------------------------------------------- 00117 inline void notify_receivers( EnergyPreservationActivity value ) 00118 { 00119 if (callback_) 00120 callback_( value ); 00121 } 00123 // -------------------------------------------------------------------- 00126 void receive( node_id_t from, size_t len, block_data_t *data ); 00128 // -------------------------------------------------------------------- 00131 void enable_transmission_phase( void *userdata ); 00132 void algorithm_step( void *userdata ); 00133 void disable_transmission_phase( void *userdata ); 00135 // -------------------------------------------------------------------- 00136 inline double activity() 00137 { return S_; } 00138 // -------------------------------------------------------------------- 00139 inline double battery() 00140 { 00141 return battery_; 00142 } 00143 // -------------------------------------------------------------------- 00144 inline void set_battery( double battery ) 00145 { 00146 if ( battery < 0.0 ) 00147 battery = 0.0; 00148 if ( battery > 1.0 ) 00149 battery = 1.0; 00150 battery_ = battery; 00151 } 00152 // -------------------------------------------------------------------- 00153 inline bool active() 00154 { return active_; } 00155 // -------------------------------------------------------------------- 00156 double sun( time_t time ); 00157 // -------------------------------------------------------------------- 00158 int init( Radio& radio, Timer& timer, Clock& clock, Debug& debug ) 00159 { 00160 radio_ = &radio; 00161 timer_ = &timer; 00162 clock_ = &clock; 00163 debug_ = &debug; 00164 return SUCCESS; 00165 } 00166 // -------------------------------------------------------------------- 00167 int init() 00168 { 00169 enable(); 00170 return SUCCESS; 00171 } 00172 // -------------------------------------------------------------------- 00173 int destruct() 00174 { 00175 disable(); 00176 return SUCCESS; 00177 } 00178 00179 private: 00180 Radio& radio() 00181 { return *radio_; } 00182 // -------------------------------------------------------------------- 00183 Timer& timer() 00184 { return *timer_; } 00185 // -------------------------------------------------------------------- 00186 Clock& clock() 00187 { return *clock_; } 00188 // -------------------------------------------------------------------- 00189 Debug& debug() 00190 { return *debug_; } 00191 // -------------------------------------------------------------------- 00192 typename Radio::self_pointer_t radio_; 00193 typename Timer::self_pointer_t timer_; 00194 typename Clock::self_pointer_t clock_; 00195 typename Debug::self_pointer_t debug_; 00196 // -------------------------------------------------------------------- 00197 void energy_harvest( time_t t1, time_t t2 ); 00198 void consume_energy(); 00199 void update_active_state(); 00200 void try_spontaneous_awakening(); 00201 void update_radius(); 00202 void update_probability_awakening(); 00203 void update_actvity(); 00204 // -------------------------------------------------------------------- 00205 enum MessageIds 00206 { 00207 ANTS_DUTY_CYCLING_MESSAGE_ID = 147 00208 }; 00209 // -------------------------------------------------------------------- 00210 energy_preservation_delegate_t callback_; 00211 00212 double battery_; 00213 bool active_; 00214 double radius_; 00215 double transmission_range_; 00216 double application_consumption_; 00217 time_t last_time_; 00218 00219 double S_, h_, f_; 00220 00221 double energy_consumption_awake_, energy_consumption_sleep_; 00222 double activation_threshold_; 00223 double probability_awakening_; 00224 double probability_awakening_min_, probability_awakening_max_; 00225 double spontaneous_awakening_activity_level_; 00226 double radius_min_, radius_max_; 00227 double g_; 00228 double cloud_; 00229 00230 double time_step_; 00231 00232 // TODO 00233 shawn::ConstRandomVariableHandle time_step_rnd_; 00234 shawn::ConstRandomVariableHandle uni_rnd_; 00235 }; 00236 // ----------------------------------------------------------------------- 00237 // ----------------------------------------------------------------------- 00238 // ----------------------------------------------------------------------- 00239 template<typename OsModel_P, 00240 typename Radio_P, 00241 typename Timer_P, 00242 typename Clock_P, 00243 typename Debug_P> 00244 AntsDutyCyclingAlgorithm<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P>:: 00245 AntsDutyCyclingAlgorithm() 00246 : callback_ ( energy_preservation_delegate_t() ), 00247 battery_ ( 1.0 ), 00248 active_ ( true ), 00249 radius_ ( 0.8 ), 00250 transmission_range_ ( 1.0 ), 00251 application_consumption_ ( 0.001 ), 00252 last_time_ ( time_t() ), 00253 S_ ( 0 ), 00254 h_ ( 0 ), 00255 f_ ( 0.0027 ) 00256 {}; 00257 // ----------------------------------------------------------------------- 00258 template<typename OsModel_P, 00259 typename Radio_P, 00260 typename Timer_P, 00261 typename Clock_P, 00262 typename Debug_P> 00263 AntsDutyCyclingAlgorithm<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P>:: 00264 ~AntsDutyCyclingAlgorithm() 00265 { 00266 #ifdef ANTS_DUTY_CYCLING_DEBUG 00267 debug().debug( "AntsDutyCyclingAlgorithm:dtor\n" ); 00268 #endif 00269 }; 00270 // ----------------------------------------------------------------------- 00271 template<typename OsModel_P, 00272 typename Radio_P, 00273 typename Timer_P, 00274 typename Clock_P, 00275 typename Debug_P> 00276 void 00277 AntsDutyCyclingAlgorithm<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P>:: 00278 enable( void ) 00279 { 00280 #ifdef ANTS_DUTY_CYCLING_DEBUG 00281 debug().debug( "AntsDutyCyclingAlgorithm: Boot for %i\n", radio().id( ) ); 00282 #endif 00283 00284 // TODO: 00285 // os()->proc->owner_w().template write_simple_tag<double>( "battery", 1.0 ); 00286 // os()->proc->owner_w().template write_simple_tag<double>( "consumed-app", 0.0 ); 00287 // os()->proc->owner_w().template write_simple_tag<double>( "consumed-rx", 0.0 ); 00288 // os()->proc->owner_w().template write_simple_tag<double>( "consumed-tx", 0.0 ); 00289 // os()->proc->owner_w().template write_simple_tag<double>( "consumed-idle", 0.0 ); 00290 // os()->proc->owner_w().template write_simple_tag<double>( "consumed-active", 0.0 ); 00291 00292 radio().enable_radio( ); 00293 radio().template reg_recv_callback<self_type, &self_type::receive>( this ); 00294 00295 active_ = true; 00296 notify_receivers( EPA_ACTIVE ); 00297 radio().set_app_active( active_ ); 00298 00299 last_time_ = clock().time( ); 00300 00301 time_t next_step = 1 - (clock().time( ) - (int)clock().time( )); 00302 timer().template set_timer<self_type, &self_type::enable_transmission_phase>( 00303 int(next_step * 1000), this, 0 ); 00304 } 00305 // ----------------------------------------------------------------------- 00306 template<typename OsModel_P, 00307 typename Radio_P, 00308 typename Timer_P, 00309 typename Clock_P, 00310 typename Debug_P> 00311 void 00312 AntsDutyCyclingAlgorithm<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P>:: 00313 disable( void ) 00314 { 00315 #ifdef ANTS_DUTY_CYCLING_DEBUG 00316 debug().debug( "AntsDutyCyclingAlgorithm: Disable\n" ); 00317 #endif 00318 // TODO 00319 // radio().unreg_recv_callback( callback_id_ ); 00320 radio().disable( ); 00321 } 00322 // ----------------------------------------------------------------------- 00323 template<typename OsModel_P, 00324 typename Radio_P, 00325 typename Timer_P, 00326 typename Clock_P, 00327 typename Debug_P> 00328 void 00329 AntsDutyCyclingAlgorithm<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P>:: 00330 set_configuration( void ) 00331 { 00332 // TODO: 00333 // const shawn::SimulationEnvironment& se = os_->proc->owner().world(). 00334 // simulation_controller().environment(); 00335 // 00336 // // TODO 00337 // uni_rnd_ = os_->proc->owner().world().simulation_controller(). 00338 // random_variable_keeper().find( "uni[0;1]" ); 00339 // 00340 // // TODO 00341 // std::string time_step_prob = se.required_string_param( "time_step_prob" ); 00342 // time_step_rnd_ = os_->proc->owner().world().simulation_controller(). 00343 // random_variable_keeper().find( time_step_prob ); 00344 // time_step_ = *time_step_rnd_; 00345 // 00346 // // TODO 00347 // energy_consumption_awake_ = se.optional_double_param( 00348 // "energy_consumption_awake", energy_consumption_awake_ ); 00349 // energy_consumption_sleep_ = se.optional_double_param( 00350 // "energy_consumption_sleep", energy_consumption_sleep_ ); 00351 // activation_threshold_ = se.optional_double_param( 00352 // "activation_threshold", activation_threshold_ ); 00353 // probability_awakening_min_ = se.optional_double_param( 00354 // "probability_awakening_min", probability_awakening_min_ ); 00355 // probability_awakening_max_ = se.optional_double_param( 00356 // "probability_awakening_max", probability_awakening_max_ ); 00357 // spontaneous_awakening_activity_level_ = se.optional_double_param( 00358 // "spontaneous_awakening_activity_level", spontaneous_awakening_activity_level_ ); 00359 // radius_min_ = se.optional_double_param( 00360 // "radius_min", radius_min_ ); 00361 // radius_max_ = se.optional_double_param( 00362 // "radius_max", radius_max_ ); 00363 // // parameter already set for disk graph model 00364 // transmission_range_ = se.required_double_param( "range" ); 00365 // application_consumption_ = se.optional_double_param( 00366 // "application_consumption", application_consumption_ ); 00367 // g_ = se.optional_double_param( "g", g_ ); 00368 // cloud_ = se.optional_double_param( "cloud", cloud_ ); 00369 // 00370 // S_ = spontaneous_awakening_activity_level_; 00371 // h_ = S_; 00372 // 00373 // probability_awakening_ = 0.0; 00374 } 00375 // ----------------------------------------------------------------------- 00376 template<typename OsModel_P, 00377 typename Radio_P, 00378 typename Timer_P, 00379 typename Clock_P, 00380 typename Debug_P> 00381 void 00382 AntsDutyCyclingAlgorithm<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P>:: 00383 receive( node_id_t from, size_t len, block_data_t *data ) 00384 { 00385 if ( from == radio().id() ) 00386 return; 00387 00388 message_id_t msg_id = *data; 00389 if ( msg_id == ANTS_DUTY_CYCLING_MESSAGE_ID ) 00390 { 00391 Message *message = (Message *)data; 00392 h_ += message->activity(); 00393 } 00394 } 00395 // ----------------------------------------------------------------------- 00396 template<typename OsModel_P, 00397 typename Radio_P, 00398 typename Timer_P, 00399 typename Clock_P, 00400 typename Debug_P> 00401 void 00402 AntsDutyCyclingAlgorithm<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P>:: 00403 enable_transmission_phase( void *userdata ) 00404 { 00405 radio().enable( ); 00406 timer().template set_timer<self_type, &self_type::algorithm_step>( 00407 int(time_step_ * 1000), this, 0 ); 00408 } 00409 // ----------------------------------------------------------------------- 00410 template<typename OsModel_P, 00411 typename Radio_P, 00412 typename Timer_P, 00413 typename Clock_P, 00414 typename Debug_P> 00415 void 00416 AntsDutyCyclingAlgorithm<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P>:: 00417 algorithm_step( void *userdata ) 00418 { 00419 #ifdef ANTS_DUTY_CYCLING_DEBUG 00420 // debug().debug( "AntsDutyCyclingAlgorithm: step at %i at %f \n", radio().id( ), os_->proc->owner().world().current_time() ); 00421 #endif 00422 // TODO 00423 // energy_harvest( last_time_, os_->proc->owner().world().current_time() ); 00424 consume_energy(); 00425 00426 if ( battery_ < 0.01 ) 00427 { 00428 active_ = false; 00429 notify_receivers( EPA_INACTIVE ); 00430 radio().set_app_active( active_ ); 00431 S_ = 0.0; 00432 } 00433 else 00434 { 00435 update_actvity(); 00436 update_active_state(); 00437 update_probability_awakening(); 00438 try_spontaneous_awakening(); 00439 update_radius(); 00440 if (active_) 00441 { 00442 Message message; 00443 message.set_msg_id( ANTS_DUTY_CYCLING_MESSAGE_ID ); 00444 message.set_activity( S_ ); 00445 radio().send( radio().BROADCAST_ADDRESS, 00446 message.buffer_size(), (block_data_t*)&message ); 00447 } 00448 } 00449 00450 last_time_ = clock().time( ); 00451 timer().template set_timer<self_type, &self_type::disable_transmission_phase>( 00452 int(time_step_ * 1000), this, 0 ); 00453 } 00454 // ----------------------------------------------------------------------- 00455 template<typename OsModel_P, 00456 typename Radio_P, 00457 typename Timer_P, 00458 typename Clock_P, 00459 typename Debug_P> 00460 void 00461 AntsDutyCyclingAlgorithm<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P>:: 00462 disable_transmission_phase( void *userdata ) 00463 { 00464 radio().disable( ); 00465 time_t next_step = 1 - (clock().time( ) - (int)clock().time( )); 00466 timer().template set_timer<self_type, &self_type::enable_transmission_phase>( 00467 int(next_step * 1000), this, 0 ); 00468 } 00469 // ---------------------------------------------------------------------- 00470 template<typename OsModel_P, 00471 typename Radio_P, 00472 typename Timer_P, 00473 typename Clock_P, 00474 typename Debug_P> 00475 double 00476 AntsDutyCyclingAlgorithm<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P>:: 00477 sun( time_t t ) 00478 { 00479 while (t >= 1440.) 00480 t -= 1440.; 00481 00482 if (t >= 420. and t < 1140.) 00483 return (1. - cos(2. * M_PI * (t - 420.) / (1140. - 420.))) / 2.; 00484 return 0.; 00485 } 00486 // ---------------------------------------------------------------------- 00487 template<typename OsModel_P, 00488 typename Radio_P, 00489 typename Timer_P, 00490 typename Clock_P, 00491 typename Debug_P> 00492 void 00493 AntsDutyCyclingAlgorithm<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P>:: 00494 energy_harvest( time_t t1, time_t t2 ) 00495 { 00496 assert( t2 > t1 ); 00497 double bat = battery() + 00498 f_ * ((t2 - t1) * ((sun(t1) + sun(t2))*(1-cloud_) / 2)); 00499 set_battery( bat ); 00500 // TODO 00501 // os()->proc->owner_w().template write_simple_tag<double>( "battery", battery_ ); 00502 } 00503 // ---------------------------------------------------------------------- 00504 template<typename OsModel_P, 00505 typename Radio_P, 00506 typename Timer_P, 00507 typename Clock_P, 00508 typename Debug_P> 00509 void 00510 AntsDutyCyclingAlgorithm<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P>:: 00511 consume_energy() 00512 { 00513 // set by the energy consumption radio 00514 //TODO 00515 // double e = os()->proc->owner().template read_simple_tag<double>( "energy" ); 00516 // set_battery( battery() - e / 2600. ); 00517 // TODO 00518 // os()->proc->owner_w().template write_simple_tag<double>( "battery", battery_ ); 00519 // os()->proc->owner_w().template write_simple_tag<double>( "energy", 0.0 ); 00520 00521 // fixed/constant application consumption if active 00522 if (active_) 00523 { 00524 set_battery( battery() - application_consumption_ ); 00525 00526 // TODO 00527 // double consumed = os()->proc->owner().template read_simple_tag<double>( "consumed-app" ); 00528 // consumed += application_consumption_; 00529 // TODO: 00530 // os()->proc->owner_w().template write_simple_tag<double>( "consumed-app", consumed ); 00531 } 00532 } 00533 // ---------------------------------------------------------------------- 00534 template<typename OsModel_P, 00535 typename Radio_P, 00536 typename Timer_P, 00537 typename Clock_P, 00538 typename Debug_P> 00539 void 00540 AntsDutyCyclingAlgorithm<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P>:: 00541 update_active_state() 00542 { 00543 if ( S_ >= activation_threshold_ ) 00544 { 00545 active_ = true; 00546 notify_receivers( EPA_ACTIVE ); 00547 } 00548 else 00549 { 00550 active_ = false; 00551 notify_receivers( EPA_INACTIVE ); 00552 } 00553 radio().set_app_active( active_ ); 00554 } 00555 // ---------------------------------------------------------------------- 00556 template<typename OsModel_P, 00557 typename Radio_P, 00558 typename Timer_P, 00559 typename Clock_P, 00560 typename Debug_P> 00561 void 00562 AntsDutyCyclingAlgorithm<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P>:: 00563 try_spontaneous_awakening() 00564 { 00565 if ( !active_ ) 00566 { 00567 // TODO 00568 double p = *uni_rnd_; 00569 if ( p <= probability_awakening_ ) 00570 { 00571 S_ = spontaneous_awakening_activity_level_; 00572 active_ = true; 00573 notify_receivers( EPA_ACTIVE ); 00574 radio().set_app_active( active_ ); 00575 } 00576 } 00577 } 00578 // ---------------------------------------------------------------------- 00579 template<typename OsModel_P, 00580 typename Radio_P, 00581 typename Timer_P, 00582 typename Clock_P, 00583 typename Debug_P> 00584 void 00585 AntsDutyCyclingAlgorithm<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P>:: 00586 update_radius() 00587 { 00588 radius_ = radius_min_ * ( 1 - battery_ ) + radius_max_ * battery_; 00589 00590 double ratio = radius_ / transmission_range_; 00591 double value = ratio; 00592 if ( ratio <= .15/2.) 00593 value = 0.; 00594 else if( ratio <= (.15+.32)/2. ) 00595 value = 0.15; 00596 else if( ratio <= (.32+.49)/2. ) 00597 value = 0.32; 00598 else if( ratio <= (.49+.66)/2. ) 00599 value = 0.49; 00600 else if( ratio <= (.66+.83)/2. ) 00601 value = 0.66; 00602 else if( ratio <= (.83+.1)/2. ) 00603 value = 0.83; 00604 else 00605 value = 1.0; 00606 00607 // if ( ratio <= .15 ) 00608 // value = 0.15; 00609 // else if( ratio <= .32 ) 00610 // value = 0.32; 00611 // else if( ratio <= .49 ) 00612 // value = 0.49; 00613 // else if( ratio <= .66 ) 00614 // value = 0.66; 00615 // else if( ratio <= .83 ) 00616 // value = 0.83; 00617 // else 00618 // value = 1.0; 00619 00620 // std::cout << "UPADTE to " << ratio << "; value is " << value << std::endl; 00621 00622 // TODO 00623 // os_->proc->owner_w().set_transmission_range( value ); 00624 } 00625 // ---------------------------------------------------------------------- 00626 template<typename OsModel_P, 00627 typename Radio_P, 00628 typename Timer_P, 00629 typename Clock_P, 00630 typename Debug_P> 00631 void 00632 AntsDutyCyclingAlgorithm<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P>:: 00633 update_probability_awakening() 00634 { 00635 probability_awakening_ = 00636 probability_awakening_min_ * ( 1 - battery_ ) + 00637 probability_awakening_max_ * battery_; 00638 } 00639 // ---------------------------------------------------------------------- 00640 template<typename OsModel_P, 00641 typename Radio_P, 00642 typename Timer_P, 00643 typename Clock_P, 00644 typename Debug_P> 00645 void 00646 AntsDutyCyclingAlgorithm<OsModel_P, Radio_P, Timer_P, Clock_P, Debug_P>:: 00647 update_actvity() 00648 { 00649 S_ = tanh(g_*h_); 00650 h_ = S_; 00651 } 00652 00653 } 00654 #endif