Update of /cvsroot/playerstage/code/stage/src
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6713/src

Modified Files:
        gui.h model_wifi.cc raytrace.c stage.h stage_internal.h 
Log Message:
added Wifi model, more or less untested, from Michael Schroeder. Comments 
welcome

Index: raytrace.c
===================================================================
RCS file: /cvsroot/playerstage/code/stage/src/raytrace.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -C2 -d -r1.17 -r1.18
*** raytrace.c  22 Mar 2006 08:46:29 -0000      1.17
--- raytrace.c  11 Sep 2007 21:30:09 -0000      1.18
***************
*** 255,258 ****
--- 255,379 ----
  }
  
+ // This method calculates the distance in meters which the signal
+ // has to travel through walls, stones and obstacles, which are also
+ // visible to lasers! Most of the code is taken from the already existing
+ // itl_first_matching routine above!
+ 
+ double itl_wall_distance( itl_t* itl,
+                                     stg_itl_test_func_t func,
+                                     stg_model_t* finder, stg_model_t* 
otherrobot) {
+   itl->index = 0;
+   itl->models = NULL;
+   stg_cell_t* cell = itl->matrix->root;
+   stg_model_t* found = NULL;
+   double through_dist = 0;
+ 
+   double xstart, ystart;
+   stg_model_t* hitting = NULL; // What model we're travelling through
+   stg_model_t* last_model = NULL; // What model we just left.
+   double justoutm = 0; // "When" we just left this model.
+ 
+       
+ 
+   while (LT(itl->range, itl->max_range)) {
+     // Locate the leaf cell at X, Y
+     cell = stg_cell_locate( cell, itl->x, itl->y );
+ 
+     if ( cell == NULL ) {
+       // done. 
+       itl->range = itl->max_range;
+       if (hitting != NULL) {}
+       return through_dist;
+     }
+ 
+     if ( fig_debug_rays )
+       stg_rtk_fig_rectangle( fig_debug_rays, cell->x, cell->y, 0, cell->size, 
cell->size, 0);
+ 
+     if (cell->data) { // not empty
+       stg_model_t* hitmod = gslist_first_matching( (GSList*) cell->data, 
func, finder ); 
+ 
+       if (!stg_model_is_related(otherrobot,hitmod)) {
+         // We hit something which matched // we should check if its the robot
+         if (hitmod == hitting) { 
+            //printf("Coming out: %s %f\n", hitmod->token, through_dist);
+            // Coming out of the object
+            last_model = hitting;
+            justoutm = 0;
+            hitting = NULL; 
+         } else if (hitting == NULL) { 
+            if ((last_model == hitmod) && (justoutm < 0.1)) {} 
+                                        else {
+              hitting = hitmod;
+            }
+         }
+       }
+     } 
+     
+     double c = itl->y - itl->tana * itl->x;
+ 
+     double xleave = itl->x;
+     double yleave = itl->y;
+ 
+     if ( GT(itl->a, 0) ) { // upwards
+       yleave = cell->ymax; // top edge
+       xleave = (yleave - c) / itl->tana;
+ 
+       // if the edge crossing was not in cell bounds
+       if (!(GTE(xleave,cell->xmin) && LT(xleave,cell->xmax))) {
+         // it must have left the cell on the left or right instead
+ 
+         if (GT(itl->a, M_PI/2.0)) {
+           xleave = cell->xmin-0.0001;
+         } else {
+           xleave = cell->xmax;
+         }
+ 
+         yleave = itl->tana * xleave + c;
+       }
+     } else { // bottom edge?
+       yleave = cell->ymin;
+       xleave = (yleave - c) / itl->tana;
+ 
+       if (!(GTE(xleave,cell->xmin) && LT(xleave,cell->xmax))) {
+         // left or right instead
+         if (LT(itl->a,-M_PI/2.0)) {
+           xleave = cell->xmin-0.00001;
+         } else {
+           xleave = cell->xmax;
+         }
+ 
+         yleave = itl->tana * xleave + c;
+       } else {
+         yleave -= 0.00001;
+       }
+     }
+ 
+     if ( fig_debug_rays ) { // draw the ray going through the rectangle
+       stg_rtk_fig_color_rgb32 ( fig_debug_rays, 0xFFBBBBB );
+       stg_rtk_fig_arrow_ex ( fig_debug_rays, itl->x, itl->y, xleave, yleave, 
0.01 );
+       stg_rtk_fig_color_rgb32 ( fig_debug_rays, 0xFF00000 );
+     }
+ 
+     // jump to the leave point
+     double distance = hypot( yleave - itl->y, xleave - itl->x );
+     itl->range += distance;
+               itl->x = xleave; 
+               itl->y = yleave;
+     if (hitting != NULL) {
+       through_dist += distance;
+     } else { 
+       justoutm += distance;
+     }
+   }
+       
+   if (hitting != NULL) {
+      //printf("Finished");
+   }
+ 
+   return through_dist;
+ 
+ }
+ 
+ 
  
  

Index: stage_internal.h
===================================================================
RCS file: /cvsroot/playerstage/code/stage/src/stage_internal.h,v
retrieving revision 1.59
retrieving revision 1.60
diff -C2 -d -r1.59 -r1.60
*** stage_internal.h    27 Jul 2006 02:33:02 -0000      1.59
--- stage_internal.h    11 Sep 2007 21:30:09 -0000      1.60
***************
*** 567,570 ****
--- 567,573 ----
                                   stg_model_t* finder );
  
+       double itl_wall_distance( itl_t* itl,
+                   stg_itl_test_func_t func,
+                   stg_model_t* finder, stg_model_t* otherrobot);
    /** @} */
  

Index: gui.h
===================================================================
RCS file: /cvsroot/playerstage/code/stage/src/gui.h,v
retrieving revision 1.36
retrieving revision 1.37
diff -C2 -d -r1.36 -r1.37
*** gui.h       27 Jul 2006 02:33:02 -0000      1.36
--- gui.h       11 Sep 2007 21:30:09 -0000      1.37
***************
*** 52,55 ****
--- 52,58 ----
  #define STG_LAYER_BUMPERDATA 62
  
+ #define STG_LAYER_WIFICONFIG 64
+ #define STG_LAYER_WIFIDATA 65
+ 
  #define STG_RANGER_COLOR "gray75" 
  #define STG_RANGER_GEOM_COLOR "orange"
***************
*** 70,73 ****
--- 73,80 ----
  #define STG_LASER_BRIGHT_COLOR "blue"
  
+ #define STG_WIFI_CFG_COLOR "royal blue"
+ #define STG_WIFI_CFG_COLOR_GREEN "DarkGreen"
+ 
+ 
  #define STG_LAYER_GRIPPERGEOM 85
  #define STG_LAYER_GRIPPERDATA 87

Index: stage.h
===================================================================
RCS file: /cvsroot/playerstage/code/stage/src/stage.h,v
retrieving revision 1.192
retrieving revision 1.193
diff -C2 -d -r1.192 -r1.193
*** stage.h     5 Sep 2007 19:01:43 -0000       1.192
--- stage.h     11 Sep 2007 21:30:09 -0000      1.193
***************
*** 1063,1070 ****
    typedef struct
    {
!     // Configuration for the wifi model goes here.  E.g., power, range of
!     // propagation.
    } stg_wifi_config_t;
  
    /** wifi data packet 
     */
--- 1063,1095 ----
    typedef struct
    {
!               char essid[32];
!               char mac[32];
!     char ip[32];
!     double power;
!     double sensitivity;
!               double freq;
!     stg_meters_t range;
!               char model[32];
!               double plc; // distance power loss coefficient
!               double ple; // path loss distance exponent
!               double sigma; // standard derivation of gaussian random variable
!               double range_db; // setting the individual ranges to render in 
render_cfg 
!               double wall_factor;
    } stg_wifi_config_t;
  
+   /** wifi sample packet
+   */
+   typedef struct
+   {
+     // this is how an entry in neighbours looks like
+     stg_pose_t pose; // global pose of corresponding neighbour
+               char essid[32];
+               char mac[32];    
+               char ip[32]; // IP adress of corresponding card
+               double freq;
+     double db; // signal-strength
+               
+   } stg_wifi_sample_t;
+ 
    /** wifi data packet 
     */
***************
*** 1073,1076 ****
--- 1098,1102 ----
      // Simulated wifi data goes here.  E.g., for each neighbor within
      // range, record the corresponding signal strength.
+   GArray* neighbours;
    } stg_wifi_data_t;
  

Index: model_wifi.cc
===================================================================
RCS file: /cvsroot/playerstage/code/stage/src/model_wifi.cc,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** model_wifi.cc       2 Mar 2006 23:19:03 -0000       1.1
--- model_wifi.cc       11 Sep 2007 21:30:09 -0000      1.2
***************
*** 2,7 ****
  //
  // File: model_wifi.cc
! // Authors: Benoit Morisset
! // Date: 2 March 2006
  //
  // CVS info:
--- 2,7 ----
  //
  // File: model_wifi.cc
! // Authors: Michael Schroeder
! // Date: 10 July 2007
  //
  // CVS info:
***************
*** 16,42 ****
  @defgroup model_wifi Wifi model 
  
! @todo Fill this in
  
  <h2>Worldfile properties</h2>
  
! @todo Fill this in
  
- */
  
  
  #include <sys/time.h>
  #include <math.h>
  #include "gui.h"
  
- // Number pulled directly from my ass
- #define STG_WIFI_WATTS 2.5
  
! //#define DEBUG
  
- #include "stage_internal.h"
  
  // standard callbacks
  extern "C" {
- 
  int wifi_update( stg_model_t* mod );
  int wifi_startup( stg_model_t* mod );
--- 16,185 ----
  @defgroup model_wifi Wifi model 
  
! The wifi model simulates a wifi device. There are currently five radio 
propagation models
! implemented. The wifi device reports simulated link information for all 
corresponding 
! nodes within range.
  
  <h2>Worldfile properties</h2>
  
! @par Simple Wifi Model
! 
! @verbatim
! wifi
! (
!       # network properties
!   ip "192.168.0.1"
!   mac "08-00-20-ae-fd-7e"
!   essid "test network"
! 
!       # radio propagation model
!   model "simple"
!       range 5
! )
! @endverbatim
! For the simple model it is only necessary to specify the range property which 
serves as the
! radio propagation radius. 
  
  
+ @par Friis Outdoor Model
+ 
+ @verbatim
+ wifi
+ (
+       # network properties
+   ip "192.168.0.1"
+   mac "08-00-20-ae-fd-7e"
+   essid "test network"
  
+       # radio propagation model
+   model "friis"
+       power 30
+       sensitivity -80
+ )
+ @endverbatim
+ The friis model simulates the path loss for each link according to Friis 
Transmission Equation. Basically it serves as a free space model. The 
parameters power(dbm) and sensitivity(dbm) are mandatory.
+ 
+ 
+ @par ITU Indoor Propagation Model
+ 
+ @verbatim
+ wifi
+ (
+       # network properties
+   ip "192.168.0.1"
+   mac "08-00-20-ae-fd-7e"
+   essid "test network"
+ 
+       # radio propagation model
+   model "ITU indoor"
+       power 30
+       sensitivity -70
+       plc 30
+ )
+ @endverbatim
+ This model estimates the path loss inside rooms or closed areas. The distance 
power loss
+ coefficient must be set according to the environmental settings. Values vary 
between 20 to 35.
+ Higher values indicate higher path loss. 
+ 
+ 
+ @par Log Distance Path Loss Model
+ 
+ @verbatim
+ wifi
+ (
+       # network properties
+   ip "192.168.0.1"
+   mac "08-00-20-ae-fd-7e"
+   essid "test network"
+ 
+       # radio propagation model
+   model "log distance"
+       power 30
+       sensitivity -70
+       ple 4
+       sigma 6
+ )
+ @endverbatim
+ The Log Distance Path Loss Model approximates the total path loss inside a 
building. 
+ It uses the path loss distance exponent (ple) which varies between 1.8 and 10 
to accommodate for different environmental settings. A Gaussian random variable 
with zero mean and standard deviation sigma
+ is used to reflect shadow fading.
+ 
+ 
+ @par Simple Raytracing Model
+ 
+ @verbatim
+ wifi
+ (
+       # network properties
+   ip "192.168.0.1"
+   mac "08-00-20-ae-fd-7e"
+   essid "test network"
+ 
+       # radio propagation model
+   model "raytrace"
+       wall_factor 10
+ )
+ @endverbatim
+ In this model Raytracing is used to reflect wifi-blocking obstacles within 
range. The wall_factor
+ is used to specify how hard it is for the signal to penetrate obstacles. 
+ 
+ 
+ @par Details
+ - model
+   - the model to use. Choose between the five existing radio propagation 
models
+ - ip
+   - the ip to fake
+ - mac
+   - the corresponding mac addess
+ - essid
+   - networks essid
+ - freq
+   - the operating frequency [default 2450 (MHz)]
+ - power
+   - Transmitter output power in dbm [default 45 (dbm)]
+ - sensitivity
+   - Receiver sensitivity in dbm [default -75 (dbm)]
+ - range
+   - propagation radius in meters used by simple model
+ - plc
+   - power loss coefficient used by the ITU Indoor model
+ - ple
+   - power loss exponent used by the Log Distance Path Loss Model
+ - sigma
+   - standard deviation used by Log Distance Path Loss Model
+ - range_db
+   - parameter used for visualization of radio wave propagation. It is usually 
set to a negative value
+ to visualize a certain db range.
+ - wall_factor
+   - factor reflects the strength of obstacles
+ */
+ 
+ #include <assert.h>
  #include <sys/time.h>
  #include <math.h>
  #include "gui.h"
+ #include <limits.h>
+ #include "stage_internal.h"
  
  
! #define RANDOM_LIMIT INT_MAX
! #define STG_WIFI_WATTS        2.5 // wifi power consumption
! #define STG_DEFAULT_WIFI_IP   "192.168.0.1"
! #define STG_DEFAULT_WIFI_MAC "00:00:00:00:00"
! #define STG_DEFAULT_WIFI_ESSID "any"
! #define STG_DEFAULT_WIFI_POWER 45
! #define STG_DEFAULT_WIFI_FREQ 2450
! #define STG_DEFAULT_WIFI_SENSITIVITY -75
! #define STG_DEFAULT_WIFI_RANGE        0
! #define STG_DEFAULT_WIFI_PLC          30
! #define STG_DEFAULT_WIFI_SIGMA  5 // can take values from 2 to 12 or even 
higher
! #define STG_DEFAULT_WIFI_PATH_LOSS_EXPONENT 2.5 // 2.0 for free space, 
!                                                                               
                                                                                
                                // 1.8 in corridor, higher 
!                                                                               
                                                                                
                                // values indicate more obstacles
! #define STG_DEFAULT_WIFI_RANGE_DB -50 //in dbm
! #define STG_DEFAULT_WIFI_WALL_FACTOR 1
  
  
  // standard callbacks
  extern "C" {
  int wifi_update( stg_model_t* mod );
  int wifi_startup( stg_model_t* mod );
***************
*** 44,62 ****
  void wifi_load( stg_model_t* mod );
  
  int wifi_render_data( stg_model_t* mod, void* userp );
  int wifi_unrender_data( stg_model_t* mod, void* userp );
  
! void 
! wifi_load( stg_model_t* mod )
  {
!   stg_wifi_config_t cfg;
  
!   // TODO: read wifi params from the world file
!   
!   stg_model_set_cfg( mod, &cfg, sizeof(cfg));
  }
  
! int 
! wifi_init( stg_model_t* mod )
  {
    // we don't consume any power until subscribed
--- 187,244 ----
  void wifi_load( stg_model_t* mod );
  
+ int wifi_render_cfg( stg_model_t* mod, void* userp );
+ int wifi_unrender_cfg( stg_model_t* mod, void* userp );
  int wifi_render_data( stg_model_t* mod, void* userp );
  int wifi_unrender_data( stg_model_t* mod, void* userp );
  
! static stg_color_t cfg_color = 0;
! static stg_color_t cfg_color_green= 0;
! // variable to save outcome of random variable
! static double norand; 
! static double power_dbm;
! 
! void wifi_load( stg_model_t* mod )
  {
!   stg_wifi_config_t* cfg = (stg_wifi_config_t*) mod->cfg;
  
!   // read wifi parameters from worldfile
!       strncpy(cfg->ip, wf_read_string(mod->id, "ip", cfg->ip), 32 );
!       strncpy(cfg->mac, wf_read_string(mod->id, "mac", cfg->mac), 32 );
!       strncpy(cfg->essid, wf_read_string(mod->id, "essid", cfg->essid), 32 );
!   cfg->power          = wf_read_float( mod->id, "power", cfg->power);
!       cfg->freq                       = wf_read_float( mod->id, "freq", 
cfg->freq);  
!       cfg->sensitivity        = wf_read_float( mod->id, "sensitivity", 
cfg->sensitivity);
!   cfg->range          = wf_read_length( mod->id, "range", cfg->range);
!       strncpy(cfg->model, wf_read_string(mod->id, "model", cfg->model), 32);
!       cfg->plc                        = wf_read_float( mod->id, "plc", 
cfg->plc);
!       cfg->ple                        = wf_read_float( mod->id, "ple", 
cfg->ple);
!       cfg->sigma              = wf_read_float( mod->id, "sigma", cfg->sigma);
!       // specifiy db-config ranges for rendering
!       cfg->range_db           = wf_read_float( mod->id, "range_db", 
cfg->range);
!       cfg->wall_factor= wf_read_float( mod->id, "wall_factor", 
cfg->wall_factor);
!       power_dbm = 10*log10( cfg->power );
! 
!   model_change( mod, &mod->cfg );
  }
  
! // Marsaglia polar method to obtain a gaussian random variable
! double nrand(double d) // additional parameter because of update cycle
! {
!       srand(time(0)+d); // time(0) is different only every second
!       double u1,u2,s;
! 
!       do 
!               {
!                       u1= ((double) rand()/RANDOM_LIMIT)*2.0-1.0;
!                       u2= ((double) rand()/RANDOM_LIMIT)*2.0-1.0;
!                       s=u1*u1+u2*u2;
!               } 
!       while (s>=1.0);
! 
!       return ( u1*sqrt(-2* log(s) /s) );
! }
! 
! 
! int wifi_init( stg_model_t* mod )
  {
    // we don't consume any power until subscribed
***************
*** 84,100 ****
    stg_model_set_blob_return( mod, 0 );
    stg_model_set_color( mod, (stg_color_t)0 );
  
    // adds a menu item and associated on-and-off callbacks
    stg_model_add_property_toggles( mod, &mod->data,
                                  wifi_render_data, NULL,
                                  wifi_unrender_data, NULL,
                                  "wifi_data",
!                                 "wifi data",
                                  TRUE );
    return 0;
  }
  
! int 
! wifi_update( stg_model_t* mod )
  {   
    // no work to do if we're unsubscribed
--- 266,436 ----
    stg_model_set_blob_return( mod, 0 );
    stg_model_set_color( mod, (stg_color_t)0 );
+   cfg_color = stg_lookup_color(STG_WIFI_CFG_COLOR);   
+       cfg_color_green= stg_lookup_color(STG_WIFI_CFG_COLOR_GREEN);
+       
+ 
+   // set up a wifi-specific config structure
+   stg_wifi_config_t lconf;
+   memset(&lconf,0,sizeof(lconf));
+       
+       strncpy(lconf.ip, STG_DEFAULT_WIFI_IP, 32);
+       strncpy(lconf.mac, STG_DEFAULT_WIFI_MAC, 32);
+       strncpy(lconf.essid, STG_DEFAULT_WIFI_ESSID, 32);
+   lconf.power         = STG_DEFAULT_WIFI_POWER;
+   lconf.sensitivity = STG_DEFAULT_WIFI_SENSITIVITY; 
+   lconf.range         = STG_DEFAULT_WIFI_RANGE;
+       lconf.freq                              = STG_DEFAULT_WIFI_FREQ;
+       lconf.plc                                       = STG_DEFAULT_WIFI_PLC;
+       lconf.ple                                       = 
STG_DEFAULT_WIFI_PATH_LOSS_EXPONENT;
+       lconf.sigma                             = STG_DEFAULT_WIFI_SIGMA;
+       lconf.range_db          = STG_DEFAULT_WIFI_RANGE_DB;
+       lconf.wall_factor = STG_DEFAULT_WIFI_WALL_FACTOR;
+   stg_model_set_cfg( mod, &lconf, sizeof(lconf) );
+ 
+   //create array to hold the link data
+   stg_wifi_data_t data;
+   data.neighbours = g_array_new( FALSE, FALSE, sizeof( stg_wifi_sample_t ) );
+   stg_model_set_data( mod, &data, sizeof( data ) );
  
    // adds a menu item and associated on-and-off callbacks
    stg_model_add_property_toggles( mod, &mod->data,
+                                 wifi_render_cfg, NULL,
+                                 wifi_unrender_cfg, NULL,
+                                 "wifi_cfg",
+                                 "wifi range",
+                                 TRUE );
+       
+       // adds a menu item and associated on-and-off callbacks
+   stg_model_add_property_toggles( mod, &mod->data,
                                  wifi_render_data, NULL,
                                  wifi_unrender_data, NULL,
                                  "wifi_data",
!                                 "wifi connections",
                                  TRUE );
+ 
    return 0;
  }
  
! 
! int wifi_raytrace_match( stg_model_t* mod, stg_model_t* hitmod )
! {           
!   // ignore my relatives and things that are invisible to lasers
!   return( (!stg_model_is_related( mod,hitmod )) && 
!                       ( hitmod->laser_return > 0) );
! }
! 
! 
! stg_meters_t calc_distance( stg_model_t* mod1, 
!                                                                               
                                stg_model_t* mod2, 
!                                                                               
                                stg_pose_t* pose1,
!                                                                               
                                stg_pose_t* pose2 )
! {
!       itl_t* itl = NULL;
!       itl = itl_create( pose1->x, pose1->y, pose2->x, pose2->y, 
!                     mod1->world->matrix, PointToPoint );
! 
!       return itl_wall_distance( itl, wifi_raytrace_match, mod1, mod2 );
! }
! 
! 
! void append_link_information( stg_model_t* mod1, stg_model_t* mod2, double db 
)
! {
!       stg_wifi_config_t* cfg2 = (stg_wifi_config_t*) mod2->cfg;
!       stg_pose_t pose2;
!   stg_model_get_global_pose( mod2, &pose2 );
!       
!       stg_wifi_sample_t sample;
!       memset( &sample,0,sizeof( sample ) );
!       strcpy( sample.ip, cfg2->ip );
!       strcpy( sample.mac, cfg2->mac );
!       strcpy( sample.essid, cfg2->essid) ;
!       sample.db  = db;
!       sample.pose = pose2;
!       sample.freq = cfg2->freq;
!       
!       stg_wifi_data_t* data = (stg_wifi_data_t*) mod1->data;
!       g_array_append_val( data->neighbours, sample );
! }
!                                                       
! void compare_models( gpointer key, gpointer value, gpointer user )
! {
!   stg_model_t *mod1 = (stg_model_t *) user;
!   stg_model_t *mod2 = (stg_model_t *) value;
! 
!       // proceed if models are different and wifi devices
!   if ( (mod1->typerec != mod2->typerec) || 
!                        (mod1 ==mod2) || 
!                        (stg_model_is_related(mod1,mod2)) )
!    return;
! 
!   stg_pose_t pose1;
!   stg_model_get_global_pose( mod1, &pose1 );
!   stg_pose_t pose2;
!   stg_model_get_global_pose( mod2, &pose2 );
! 
!       stg_wifi_config_t* cfg1 = (stg_wifi_config_t*) mod1->cfg;
!   stg_wifi_config_t* cfg2 = (stg_wifi_config_t*) mod2->cfg;
! 
!       double distance = hypot( pose2.x-pose1.x, pose2.y-pose1.y );
!       
!       // store link information for reachable nodes
!       if ( strcmp( cfg1->model, "friis" )== 0 )
!        {
!                       double fsl                      = 
32.44177+20*log10(cfg1->freq)+20*log10(distance/1000);
!                       if( fsl<= ( power_dbm-cfg2->sensitivity ) )
!                               {
!                               append_link_information( mod1, mod2, 
power_dbm-fsl );
!                               }
!               }
! 
!       else if ( strcmp( cfg1->model, "ITU indoor" ) ==0 )
!               {
!                       double loss = 20*log10( cfg1->freq )+( cfg1->plc 
)*log10( distance )-28;
!                       if( loss<=( power_dbm-cfg2->sensitivity ) )
!                               {       
!                                       append_link_information( mod1, mod2, 
power_dbm-loss );
!                               }
!       }
! 
!       else if(strcmp(cfg1->model, "log distance" )==0 )
!       {
!               double loss_0           = 32.44177+20*log10( cfg1->freq )+
!                                                                               
        20*log10( 0.001 ); // path loss in 1 meter
!               norand = nrand( power_dbm );
!               double loss = loss_0+10*cfg1->ple*log10( distance 
)+cfg1->sigma*norand;
! 
!               if( loss<= (power_dbm-cfg2->sensitivity) )
!                       {
!                       append_link_information(mod1, mod2, power_dbm-loss);
!                       }
!       }
! 
!       else if( strcmp( cfg1->model, "raytrace" )==0 )
!       {
!               double loss = 20*log10( cfg1->freq )+
!                                                                       
(cfg1->plc)*log10( distance )-28;
! 
!               if( loss<= ( power_dbm-cfg2->sensitivity ) )
!               {
!                       stg_meters_t me = calc_distance( mod1, mod2, &pose1, 
&pose2 );
!                       double new_loss = cfg1->wall_factor*me*100+loss;
!                       if ( new_loss <=( power_dbm-cfg2->sensitivity ) )
!                       {
!                               append_link_information( mod1, mod2, 
power_dbm-new_loss );      
!                       }                       
!               }
!       }
! 
!       else if( strcmp( cfg1->model, "simple" )==0 )
!       {
!               if (cfg1->range >= distance)
!               {
!                       append_link_information( mod1, mod2, 1 );
!               }
!       }
! }
! 
! 
! int wifi_update( stg_model_t* mod )
  {   
    // no work to do if we're unsubscribed
***************
*** 102,176 ****
      return 0;
  
!   puts("wifi_update");
      
    // Retrieve current configuration
    stg_wifi_config_t cfg;
!   memcpy(&cfg, mod->cfg, sizeof(cfg));
  
    // Retrieve current geometry
    stg_geom_t geom;
    stg_model_get_geom( mod, &geom );
-   
-   // get the sensor's pose in global coords
-   stg_pose_t pz;
-   memcpy( &pz, &geom.pose, sizeof(pz) ); 
-   stg_model_local_to_global( mod, &pz );
  
-   
    // We'll store current data here
    stg_wifi_data_t data;
  
!   // DO RADIO PROPAGATION HERE, and fill in the data structure
  
!   // publish the new stuff
!   stg_model_set_data( mod, &data, sizeof(data));
  
-   // inherit standard update behaviour
-   _model_update( mod );
  
!   return 0; //ok
  }
  
! int 
! wifi_render_data(  stg_model_t* mod, void* userp )
  {
!   //puts( "wifi render data" );
  
!   // only draw if someone is using the gripper
    if( mod->subs < 1 )
      return 0;
  
!   // DRAW WIFI DATA HERE.  Look at other models for examples.
  
    return 0; 
  }
  
! int 
! wifi_startup( stg_model_t* mod )
  { 
    PRINT_DEBUG( "wifi startup" );
    stg_model_set_watts( mod, STG_WIFI_WATTS );
    return 0; // ok
  }
  
! int 
! wifi_shutdown( stg_model_t* mod )
  {
    PRINT_DEBUG( "wifi shutdown" );
    stg_model_set_watts( mod, 0 );
    
!   // unrender the data
!   //stg_model_fig_clear( mod, "wifi_data_fig" );
    return 0; // ok
  }
  
! int 
! wifi_unrender_data( stg_model_t* mod, void* userp )
  {
!   // CLEAR STUFF THAT YOU DREW
!   //stg_model_fig_clear( mod, "wifi_data_fig" );
    return 1; // callback just runs one time
  }
  
  }
  
--- 438,703 ----
      return 0;
  
!   //puts("\nwifi_update");
      
    // Retrieve current configuration
    stg_wifi_config_t cfg;
!   memcpy( &cfg, mod->cfg, sizeof(cfg) );
  
    // Retrieve current geometry
    stg_geom_t geom;
    stg_model_get_geom( mod, &geom );
  
    // We'll store current data here
    stg_wifi_data_t data;
+   memcpy( &data, mod->data, sizeof(data) );
  
!       g_array_free( data.neighbours, TRUE );
!  
!       data.neighbours = g_array_new( FALSE, TRUE, sizeof( stg_wifi_sample_t ) 
);
!   stg_model_set_data( mod, &data, sizeof( data ) );
  
!   g_hash_table_foreach(mod->world->models_by_name, compare_models, mod); 
!       stg_model_set_data( mod, &data, sizeof( data ) );
!       
!   return 0; //ok
! }
  
  
! 
! int wifi_render_cfg(  stg_model_t* mod, void* userp )
! {
!   
!       //puts( "\nwifi render cfg" );
!       stg_rtk_fig_t* fig = 
!   stg_model_fig_get_or_create( mod, "wifi_cfg_fig", "top", 
!                                                                               
                                         STG_LAYER_WIFICONFIG );
!   stg_rtk_fig_t* bg = 
!   stg_model_fig_get_or_create( mod, "wifi_cfg_bg_fig", "top", 
!                                                                               
                                         STG_LAYER_BACKGROUND );
!   
!   stg_rtk_fig_clear( bg );
!   stg_rtk_fig_clear( fig );
!               
!   // get config
!   stg_wifi_config_t *cfg = (stg_wifi_config_t*) mod->cfg;
!   assert( cfg ); // make sure config is available
! 
!       // get pose
!       stg_pose_t pose;
!   stg_model_get_global_pose( mod, &pose );
! 
!       // render corresponding config ranges
!       if( strcmp( cfg->model, "simple" )==0 )
!               {
!               stg_rtk_fig_ellipse( fig, 0, 0, 0, 2*cfg->range, 2*cfg->range, 
0 );
!               }
! 
!       double dist_green=0;// dist_red=0, dist_yellow=0 ;
! 
!       if ( strcmp( cfg->model, "friis" )==0 )
!               {
!                       dist_green      = pow( 10, ((-cfg->range_db+power_dbm-
!                                                                               
                                         32.44177-20*log10(cfg->freq))/20) 
)*1000;
!               }
! 
!       if ( strcmp( cfg->model, "ITU indoor" )==0 )
!               {
!                       dist_green      = pow( 10, (-cfg->range_db+power_dbm+28-
!                                                                               
                                         20*log10(cfg->freq))/cfg->plc );
!               }
! 
!       if( strcmp( cfg->model, "log distance")==0 )
!               {
!                       double loss_0   = 
32.44177+20*log10(cfg->freq)+20*log10(0.001);
!                       dist_green              = pow( 10, 
(-cfg->range_db+power_dbm-loss_0-
!                                                                               
                                                 
cfg->sigma*norand)/(10*cfg->ple) );
!               }
! 
!       if ( strcmp( cfg->model, "raytrace")==0 )
!               {
!                       double points[72][2];
!                       stg_pose_t frompose; 
!                       stg_model_get_global_pose(mod, &frompose);  
!                       double bearing = 0; 
!                       double sample_incr = (2.0 * M_PI) / 72.0;
!                       double me = 0;
!                       double actualrange = 0;
!                       double dist_red = pow( 10, (-cfg->range_db+power_dbm+
!                                                                               
                                 28-20*log10(cfg->freq))/cfg->plc );
!                       itl_t* itl = NULL;
! 
!               for ( int s = 0; s < 72; s++ )
!                       { 
!                               // calculate the maximum range!          
!                               itl = itl_create( frompose.x, frompose.y, 
bearing, dist_red,
!                                                             
mod->world->matrix, PointToBearingRange );
!                               // check the fieldstrength on first obstacle 
!                               // and in the end and just interpolate 
!                               itl_first_matching(itl, 
wifi_raytrace_match,mod);
! 
!                               double x = itl->x;
!                               double y = itl->y;
!                               double dist_to_obst = hypot(pose.x-x,pose.y-y);
!       
!                               // the ray hits an obstacle
!                               if ( dist_to_obst>0 )
!                                       {
!                                               double loss_to_obst = 
20*log10(cfg->freq)+
!                                                                               
                                                        
(cfg->plc)*log10(dist_to_obst)-28;
!                                               double loss_to_targ = 
20*log10(cfg->freq)+
!                                                                               
                                                        
(cfg->plc)*log10(dist_red)-28;          
!       
!                                               // calculate distance through 
wall
!                                               me = itl_wall_distance(itl, 
wifi_raytrace_match, mod, mod);
!                                               itl_destroy( itl );
!                                               double dis = 
(dist_red-dist_to_obst)*
!                                                                               
                 (power_dbm - cfg->range_db-loss_to_obst) /
!                                                                               
                 ((cfg->wall_factor*me*100+loss_to_targ)-loss_to_obst);
!                               
!                                               actualrange = dist_to_obst+dis; 
 
!                                       } 
!                               else 
!                                       {
!                                               actualrange= dist_red;
!                                       }
! 
!                               double x3 =actualrange * cos(bearing);
!                               double y4 =actualrange * sin(bearing);
!                       
!                               // are we inside the world?
!                               if ( -mod->world->width/2  <=  (x3+frompose.x)  
&& 
!                                                (x3+frompose.x)  <=  
mod->world->width/2   && 
!                                                -mod->world->height/2  <=  
(y4+frompose.y) && 
!                                                (y4+frompose.y) <=  
mod->world->height/2 )
!                                       {
!                                               
points[s][0]=x3*cos(-frompose.a)- sin(-frompose.a)*y4;
!                                               
points[s][1]=sin(-frompose.a)*x3 +y4*cos(-frompose.a);
!                                       } // we are outside! correct to border!
!                               else
!                                       {
!                                               double ac = 
hypot(frompose.x-x,frompose.y-y);
!                                               points[s][0]= 
ac*cos(bearing)*cos(-frompose.a)-
!                                                                               
                        sin(-frompose.a)*ac*sin(bearing);
!                                               points[s][1]= 
sin(-frompose.a)*ac*cos(bearing)+
!                                                                               
                        ac*sin(bearing)*cos(-frompose.a);
!                                       }
! 
!                               bearing += sample_incr;
!                       }
!                       // print polygons
!                       stg_rtk_fig_color_rgb32( bg, 0xc1ffc1);
!                       stg_rtk_fig_color_rgb32( fig, 0x2e8b57);
!               stg_rtk_fig_polygon( bg, 0,0,0, 72, points, TRUE );
!                       stg_rtk_fig_polygon( fig, 0, 0, 0, 72, points, 0 );
!                       return 0;
!               }
!       // print ellipses
!       stg_rtk_fig_color_rgb32( bg, 0xc1ffc1);
!       stg_rtk_fig_color_rgb32( fig, 0x2e8b57);
!       stg_rtk_fig_ellipse( fig, 0, 0, 0, 2*dist_green, 2*dist_green, 0);
!       stg_rtk_fig_ellipse( bg, 0, 0, 0, 2*dist_green, 2*dist_green, 1);
! 
!   return 0; 
  }
  
! // draw some fancy arrows to indicate connections
! void draw( stg_pose_t pose1, stg_pose_t pose2, stg_rtk_fig_t *fig )
  {
!       double length = sqrt(   pow( pose2.x-pose1.x, 2 ) + pow( 
pose2.y-pose1.y, 2 ) );
!       double neworient;
  
!       if ( pose1.x > pose2.x && pose1.y >pose2.y)
!       {
!               neworient = ( 270*3.14152/180 )-asin( ( pose1.x-pose2.x 
)/length );
!               stg_rtk_fig_arrow_fancy( fig, 0, 0, neworient-pose1.a,
!                                                                               
                                 length-0.2, 0.15, 0.01, 1 );
!       } 
!       else if( pose1.x>pose2.x && pose1.y <= pose2.y)
!       {
!               neworient = ( 90*3.14152/180 )+asin( ( pose1.x-pose2.x )/length 
);
!               stg_rtk_fig_arrow_fancy( fig, 0, 0, neworient-pose1.a,
!                                                                               
                                 length-0.2, 0.15, 0.01, 1 );
!       } 
!       else if( pose1.x<=pose2.x && pose1.y <= pose2.y )
!       {
!               neworient = -( 270*M_PI/180 )+asin( ( pose1.x-pose2.x )/length 
);               
!               stg_rtk_fig_arrow_fancy( fig, 0, 0, neworient-pose1.a,
!                                                                               
                                 length-0.2, 0.15, 0.01, 1 );
!       } 
!       else if( pose1.x<=pose2.x && pose1.y > pose2.y )
!       {
!               neworient = -( 90*3.14152/180 )-asin( ( pose1.x-pose2.x 
)/length );
!               stg_rtk_fig_arrow_fancy( fig, 0, 0, neworient-pose1.a,
!                                                                               
                                 length-0.2, 0.15, 0.01, 1 );
!       }
! }
! 
! 
! int wifi_render_data( stg_model_t* mod, void* userp )
! {
    if( mod->subs < 1 )
      return 0;
  
!       //puts("\n----------------\nrender_data");
! 
!       stg_rtk_fig_t* fig = stg_model_get_fig( mod, "wifi_data_fig" );
!   
!   if( !fig )
!     fig = stg_model_fig_create( mod, "wifi_data_fig", "top", 
STG_LAYER_WIFIDATA );
!   
!   // clear figure and get color for config visualisation
!   stg_rtk_fig_clear(fig);
!   stg_rtk_fig_color_rgb32( fig, cfg_color);
! 
!       stg_wifi_data_t* sdata = (stg_wifi_data_t*)mod->data;
!       assert(sdata);
  
+       stg_pose_t pose1;
+   stg_model_get_global_pose( mod, &pose1 );
+       
+       // only draw connections between linked nodes
+       for ( int j=0; j<sdata->neighbours->len; j++ )
+               {
+                       stg_wifi_sample_t sam_temp = g_array_index( 
sdata->neighbours, 
+                                                                               
                                                                                
                                        stg_wifi_sample_t, j );
+                       stg_pose_t pose2 = sam_temp.pose;
+                       draw(pose1, pose2, fig);
+               }
    return 0; 
  }
  
! 
! int wifi_startup( stg_model_t* mod )
  { 
    PRINT_DEBUG( "wifi startup" );
    stg_model_set_watts( mod, STG_WIFI_WATTS );
+ 
    return 0; // ok
  }
  
! 
! int wifi_shutdown( stg_model_t* mod )
  {
    PRINT_DEBUG( "wifi shutdown" );
    stg_model_set_watts( mod, 0 );
    
!   stg_model_fig_clear( mod, "wifi_cfg_fig" );
    return 0; // ok
  }
  
! 
! int wifi_unrender_cfg( stg_model_t* mod, void* userp )
  {
!   stg_model_fig_clear( mod, "wifi_cfg_fig" );
!       stg_model_fig_clear( mod, "wifi_cfg_bg_fig" );
    return 1; // callback just runs one time
  }
  
+ 
+ int wifi_unrender_data( stg_model_t* mod, void* userp )
+ {
+   stg_model_fig_clear( mod, "wifi_data_fig" );
+   return 1; // callback just runs one time
  }
  
+ }


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to