Revision: 6690 http://playerstage.svn.sourceforge.net/playerstage/?rev=6690&view=rev Author: thjc Date: 2008-06-26 03:06:47 -0700 (Thu, 26 Jun 2008)
Log Message: ----------- fix for colour matchingin blobfinder Modified Paths: -------------- code/stage/branches/release-2-1-patches/src/model_blobfinder.c Modified: code/stage/branches/release-2-1-patches/src/model_blobfinder.c =================================================================== --- code/stage/branches/release-2-1-patches/src/model_blobfinder.c 2008-06-26 02:30:22 UTC (rev 6689) +++ code/stage/branches/release-2-1-patches/src/model_blobfinder.c 2008-06-26 10:06:47 UTC (rev 6690) @@ -35,14 +35,14 @@ #define STG_DEFAULT_BLOB_CHANNELCOUNT 6 #define STG_DEFAULT_BLOB_SCANWIDTH 80 -#define STG_DEFAULT_BLOB_SCANHEIGHT 60 -#define STG_DEFAULT_BLOB_RANGEMAX 8.0 +#define STG_DEFAULT_BLOB_SCANHEIGHT 60 +#define STG_DEFAULT_BLOB_RANGEMAX 8.0 const int STG_BLOBFINDER_BLOBS_MAX = 32; const double STG_BLOB_WATTS = 10.0; // power consumption -/** +/** @ingroup model @defgroup model_blobfinder Blobfinder model @@ -80,14 +80,14 @@ - channel_count int - number of channels; i.e. the number of discrete colors detected - channels [ string ... ] - - define the colors detected in each channel, using color names from the X11 database + - define the colors detected in each channel, using color names from the X11 database (usually /usr/X11R6/lib/X11/rgb.txt). The number of strings should match channel_count. - image [int int] - [width height] - - dimensions of the image in pixels. This determines the blobfinder's + - dimensions of the image in pixels. This determines the blobfinder's resolution - ptz [float float float] - - [pan_angle tilt_angle zoom_angle] + - [pan_angle tilt_angle zoom_angle] - control the panning, tilt and zoom angle (fov) of the blobfinder. Tilt angle currently has no effect. - range_max float - maximum range of the sensor in meters. @@ -112,36 +112,36 @@ mod->f_shutdown = blobfinder_shutdown; mod->f_update = NULL;// installed at startup/shutdown mod->f_load = blobfinder_load; - - + + stg_geom_t geom; memset( &geom, 0, sizeof(geom)); stg_model_set_geom( mod, &geom ); - + stg_blobfinder_config_t cfg; memset(&cfg,0,sizeof(cfg)); - + cfg.scan_width = STG_DEFAULT_BLOB_SCANWIDTH; - cfg.scan_height = STG_DEFAULT_BLOB_SCANHEIGHT; - cfg.range_max = STG_DEFAULT_BLOB_RANGEMAX; - - cfg.channel_count = 6; + cfg.scan_height = STG_DEFAULT_BLOB_SCANHEIGHT; + cfg.range_max = STG_DEFAULT_BLOB_RANGEMAX; + + cfg.channel_count = 6; cfg.channels[0] = stg_lookup_color( "red" ); cfg.channels[1] = stg_lookup_color( "green" ); cfg.channels[2] = stg_lookup_color( "blue" ); cfg.channels[3] = stg_lookup_color( "cyan" ); cfg.channels[4] = stg_lookup_color( "yellow" ); cfg.channels[5] = stg_lookup_color( "magenta" ); - + stg_model_set_cfg( mod, &cfg, sizeof(cfg) ); - + //int c; //for( c=0; c<6; c++ ) //PRINT_WARN2( "init channel %d has val %X", c, cfg.channels[c] ); - + stg_model_set_data( mod, NULL, 0 ); stg_model_set_polygons( mod, NULL, 0 ); - + stg_model_add_callback( mod, &mod->data, blobfinder_render_data, NULL ); stg_model_add_property_toggles( mod, &mod->data, @@ -167,57 +167,57 @@ void blobfinder_load( stg_model_t* mod ) { - stg_blobfinder_config_t* now = (stg_blobfinder_config_t*)mod->cfg; + stg_blobfinder_config_t* now = (stg_blobfinder_config_t*)mod->cfg; assert(now); - + stg_blobfinder_config_t bcfg; memcpy( &bcfg, now, sizeof(bcfg)); - bcfg.channel_count = + bcfg.channel_count = wf_read_int(mod->id, "channel_count", now->channel_count ); - + bcfg.scan_width = (int) wf_read_tuple_float(mod->id, "image", 0, now->scan_width ); bcfg.scan_height = (int) - wf_read_tuple_float(mod->id, "image", 1, now->scan_height ); - bcfg.range_max = + wf_read_tuple_float(mod->id, "image", 1, now->scan_height ); + bcfg.range_max = wf_read_length(mod->id, "range_max", now->range_max ); if( bcfg.channel_count > STG_BLOB_CHANNELS_MAX ) bcfg.channel_count = STG_BLOB_CHANNELS_MAX; - + // TODO - load the channel specification properly int ch; for( ch = 0; ch<bcfg.channel_count; ch++ ) - { + { const char* colorstr = wf_read_tuple_string( mod->id, "channels", ch, NULL ); - + if( ! colorstr ) break; - - bcfg.channels[ch] = stg_lookup_color( colorstr ); - } - + + bcfg.channels[ch] = stg_lookup_color( colorstr ); + } + stg_model_set_cfg( mod, &bcfg, sizeof(bcfg)); } int blobfinder_startup( stg_model_t* mod ) { - PRINT_DEBUG( "blobfinder startup" ); - + PRINT_DEBUG( "blobfinder startup" ); + mod->f_update = blobfinder_update; //mod->watts = STG_BLOB_WATTS; - + return 0; } int blobfinder_shutdown( stg_model_t* mod ) { - PRINT_DEBUG( "blobfinder shutdown" ); - + PRINT_DEBUG( "blobfinder shutdown" ); + mod->f_update = NULL; //mod->watts = 0.0; - + // clear the data - this will unrender it too stg_model_set_data( mod, NULL, 0 ); return 0; @@ -227,7 +227,7 @@ int blobfinder_raytrace_filter( stg_model_t* finder, stg_model_t* found ) { if( found->blob_return && !stg_model_is_related( finder, found )) - return 1; + return 1; return 0; } @@ -238,8 +238,8 @@ int blobfinder_update( stg_model_t* mod ) { - PRINT_DEBUG( "blobfinder update" ); - + PRINT_DEBUG( "blobfinder update" ); + // we MUST have a PTZ parent model if( mod->parent == NULL ) { @@ -252,49 +252,48 @@ if( mod->parent->f_startup != ptz_startup ) { printf( "Model %s is a blobfinder but it's parent is not a PTZ model.\n" - "A blobfinder MUST be a child of a PTZ model. Fix your worldfile.\n", + "A blobfinder MUST be a child of a PTZ model. Fix your worldfile.\n", mod->token ); exit(-1); } - + stg_ptz_data_t* ptz = (stg_ptz_data_t*)mod->parent->data; - stg_blobfinder_config_t *cfg = (stg_blobfinder_config_t*)mod->cfg; - + stg_blobfinder_config_t *cfg = (stg_blobfinder_config_t*)mod->cfg; + // Generate the scan-line image // Get the camera's global pose - stg_pose_t pose; + stg_pose_t pose; stg_model_get_global_pose( mod, &pose ); - + double ox = pose.x; double oy = pose.y; double oth = pose.a; // Compute starting angle oth = oth + ptz->pan + ptz->zoom / 2.0; - + // Compute fov, range, etc double dth = ptz->zoom / cfg->scan_width; // Make sure the data buffer is big enough //ASSERT((size_t)m_scan_width<=sizeof(m_scan_channel)/sizeof(m_scan_channel[0])); - + //printf( "scan width %d\n", cfg->scan_width ); // record the color of every ray we project - stg_color_t* colarray = - (stg_color_t*)calloc( sizeof(stg_color_t),cfg->scan_width); + stg_color_t* colarray = + (stg_color_t*)calloc( sizeof(stg_color_t),cfg->scan_width); // record the range of every ray we project - double* rngarray = - (double*)calloc( sizeof(double),cfg->scan_width); - + double* rngarray = + (double*)calloc( sizeof(double),cfg->scan_width); + // Do each scan // Note that the scan is taken *clockwise* // i'm scanning this as half-resolution for a significant speed-up //int num_blobs = 0; - stg_color_t col; if( fig_debug_rays ) stg_rtk_fig_clear( fig_debug_rays ); @@ -303,40 +302,32 @@ { //printf( "scan %d of %d\n", s, m_scan_width ); - // indicate no valid color found (MSB normally unused in 32bit RGB value) - col = 0xFF000000; - + // Compute parameters of scan line double px = ox; double py = oy; double pth = oth - s * dth; - - itl_t* itl = itl_create( px, py, pth, - cfg->range_max, - mod->world->matrix, + + itl_t* itl = itl_create( px, py, pth, + cfg->range_max, + mod->world->matrix, PointToBearingRange ); - + stg_model_t* ent; double range = cfg->range_max; ent = itl_first_matching( itl, blobfinder_raytrace_filter, mod ); + range = itl->range; // it's this far away + itl_destroy( itl ); if( ent ) { - range = itl->range; // it's this far away - col = ent->color; // it's this color - } - - itl_destroy( itl ); - - // if we found a color on this ray - if( !(col & 0xFF000000) ) - { + stg_color_t col = ent->color; // it's this color PRINT_DEBUG3( "ray %d sees color %0X at range %.2f", s, col, range ); - + //colarray[s] = col; //rngarray[s] = range; - + // look up this color in the color/channel mapping array int c; for( c=0; c < cfg->channel_count; c++ ) @@ -347,16 +338,16 @@ if( cfg->channels[c] == col) { //printf("color %0X is channel %d\n", col, c); - + colarray[s] = c+1; rngarray[s] = range; - + break; } } } } - + //printf( "model %p colors: ", mod ); //int g; //for( g=0; g<cfg->scan_width; g++ ) @@ -369,9 +360,9 @@ int blobleft = 0, blobright = 0; unsigned char blobcol = 0; int blobtop = 0, blobbottom = 0; - + GArray* blobs = g_array_new( FALSE, TRUE, sizeof(stg_blobfinder_blob_t) ); - + // scan through the samples looking for color blobs for( s=0; s < cfg->scan_width; s++ ) { @@ -380,15 +371,15 @@ { blobleft = s; blobcol = colarray[s]; - + //printf( "blob start %d\n", blobleft ); // loop until we hit the end of the blob // there has to be a gap of >1 pixel to end a blob // this avoids getting lots of crappy little blobs - while( colarray[s] == blobcol || colarray[s+1] == blobcol ) + while( colarray[s] == blobcol || colarray[s+1] == blobcol ) s++; - + blobright = s-1; //printf( "blob end %d\n", blobright ); @@ -400,7 +391,7 @@ { // if the range to the "center" is zero, then use the range // to the start. this can happen, for example, when two 1-pixel - // blobs that are 1 pixel apart are grouped into a single blob in + // blobs that are 1 pixel apart are grouped into a single blob in // whose "center" there is really no blob at all rangeToBlobCenter = rngarray[ blobleft ]; } @@ -409,18 +400,18 @@ blobtop = cfg->scan_height/2 - (int)(startyangle/yRadsPerPixel); blobbottom = cfg->scan_height/2 -(int)(endyangle/yRadsPerPixel); int yCenterOfBlob = blobtop + ((blobbottom - blobtop )/2); - + if (blobtop < 0) blobtop = 0; if (blobbottom > cfg->scan_height - 1) blobbottom = cfg->scan_height - 1; - - + + // fill in an array entry for this blob // stg_blobfinder_blob_t blob; memset( &blob, 0, sizeof(blob) ); - + blob.channel = blobcol-1; blob.color = cfg->channels[ blob.channel]; blob.xpos = xCenterOfBlob; @@ -430,30 +421,30 @@ blob.right = blobright; blob.bottom = blobbottom; blob.area = (blobtop - blobbottom) * (blobleft-blobright); - blob.range = (int)(rangeToBlobCenter*1000.0); - + blob.range = (int)(rangeToBlobCenter*1000.0); + //printf( "Robot %p sees %d xpos %d ypos %d\n", // mod, blob.color, blob.xpos, blob.ypos ); - + // add the blob to our stash g_array_append_val( blobs, blob ); } } - //PRINT_WARN1( "blobfinder setting data %d bytes of data", + //PRINT_WARN1( "blobfinder setting data %d bytes of data", // blobs->len * sizeof(stg_blobfinder_blob_t) ); - - - stg_model_set_data( mod, - blobs->data, + + + stg_model_set_data( mod, + blobs->data, blobs->len * sizeof(stg_blobfinder_blob_t) ); - + g_array_free( blobs, TRUE ); free( colarray ); free( rngarray ); - PRINT_DEBUG( "blobfinder data service done" ); + PRINT_DEBUG( "blobfinder data service done" ); return 0; //OK } @@ -465,18 +456,18 @@ } int blobfinder_render_data( stg_model_t* mod, void* userp ) -{ - PRINT_DEBUG( "blobfinder render" ); - +{ + PRINT_DEBUG( "blobfinder render" ); + stg_blobfinder_blob_t *blobs = (stg_blobfinder_blob_t*)mod->data; int num_blobs = mod->data_len / sizeof(stg_blobfinder_blob_t); - + stg_rtk_fig_t* fig = stg_model_get_fig( mod, "blob_data_fig" ); - + if( fig == NULL ) fig = stg_model_fig_create( mod, "blob_data_fig", NULL, STG_LAYER_BLOBDATA ); - + stg_rtk_fig_clear( fig ); if( num_blobs < 1 ) @@ -486,55 +477,55 @@ stg_pose_t pose; //memset(&pose, 0, sizeof(pose)); stg_model_get_global_pose( mod, &pose ); - + pose.x -= 1.0; pose.y += 1.0; pose.a = 0.0; stg_rtk_fig_origin( fig, pose.x, pose.y, pose.a ); - + double scale = 0.01; // shrink from pixels to meters for display - - stg_blobfinder_config_t *cfg = (stg_blobfinder_config_t*)mod->cfg; - + stg_blobfinder_config_t *cfg = (stg_blobfinder_config_t*)mod->cfg; + + short width = cfg->scan_width; short height = cfg->scan_height; double mwidth = width * scale; double mheight = height * scale; - + // the view outline rectangle stg_rtk_fig_color_rgb32(fig, 0xFFFFFF); - stg_rtk_fig_rectangle(fig, 0.0, 0.0, 0.0, mwidth, mheight, 1 ); + stg_rtk_fig_rectangle(fig, 0.0, 0.0, 0.0, mwidth, mheight, 1 ); stg_rtk_fig_color_rgb32(fig, 0x000000); - stg_rtk_fig_rectangle(fig, 0.0, 0.0, 0.0, mwidth, mheight, 0); - + stg_rtk_fig_rectangle(fig, 0.0, 0.0, 0.0, mwidth, mheight, 0); + int c; for( c=0; c<num_blobs; c++) { stg_blobfinder_blob_t* blob = &blobs[c]; - + // set the color from the blob data - stg_rtk_fig_color_rgb32( fig, blob->color ); - + stg_rtk_fig_color_rgb32( fig, blob->color ); + short top = blob->top; short bot = blob->bottom; short left = blob->left; short right = blob->right; - + double mtop = top * scale; double mbot = bot * scale; double mleft = left * scale; double mright = right * scale; - + // get the range in meters - //double range = (double)ntohs(data.blobs[index+b].range) / 1000.0; - - stg_rtk_fig_rectangle(fig, - -mwidth/2.0 + (mleft+mright)/2.0, + //double range = (double)ntohs(data.blobs[index+b].range) / 1000.0; + + stg_rtk_fig_rectangle(fig, + -mwidth/2.0 + (mleft+mright)/2.0, -mheight/2.0 + (mtop+mbot)/2.0, - 0.0, - mright-mleft, - mbot-mtop, + 0.0, + mright-mleft, + mbot-mtop, 1 ); } @@ -558,24 +549,24 @@ stg_blobfinder_config_t *cfg = (stg_blobfinder_config_t*)mod->cfg; assert(cfg); - + stg_pose_t* pose = &mod->pose; - + double ox = pose->x; double oy = pose->y; double mina = pose->a + (ptz->pan + ptz->zoom / 2.0); double maxa = pose->a + (ptz->pan - ptz->zoom / 2.0); - + double dx = cfg->range_max * cos(mina); double dy = cfg->range_max * sin(mina); double ddx = cfg->range_max * cos(maxa); double ddy = cfg->range_max * sin(maxa); - + stg_rtk_fig_t* fig = stg_model_get_fig( mod, "blob_cfg_fig" ); - + if( fig == NULL ) fig = stg_model_fig_create( mod, "blob_cfg_fig", "top", STG_LAYER_BLOBDATA ); - + stg_rtk_fig_clear( fig ); stg_rtk_fig_color_rgb32( fig, stg_lookup_color( STG_BLOB_CFG_COLOR )); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------- Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://sourceforge.net/services/buy/index.php _______________________________________________ Playerstage-commit mailing list Playerstage-commit@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/playerstage-commit