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

Added Files:
      Tag: opengl
        draw.cc model_blobfinder.cc 
Log Message:
added missing files

--- NEW FILE: draw.cc ---
/* Author: Richard Vaughan
   Date
#include "stage_internal.hh"


--- NEW FILE: model_blobfinder.cc ---
 ///////////////////////////////////////////////////////////////////////////
 //
 // File: model_blobfinder.c
 // Author: Richard Vaughan
 // Date: 10 June 2004
 //
 // CVS info:
 //  $Source: 
/cvsroot/playerstage/code/stage/libstage/Attic/model_blobfinder.cc,v $
 //  $Author: rtv $
 //  $Revision: 1.1.2.1 $
 //
 ///////////////////////////////////////////////////////////////////////////

 //#define DEBUG 

#include <sys/time.h>
#include "stage_internal.hh"

static const stg_watts_t DEFAULT_BLOBFINDERWATTS = 2.0;
static const stg_meters_t DEFAULT_BLOBFINDERRANGE = 12.0;
static const stg_radians_t DEFAULT_BLOBFINDERFOV = M_PI/3.0;
static const stg_radians_t DEFAULT_BLOBFINDERPAN = 0.0;
static const unsigned int DEFAULT_BLOBFINDERINTERVAL_MS = 100;
static const unsigned int DEFAULT_BLOBFINDERRESOLUTION = 1;
static const unsigned int DEFAULT_BLOBFINDERSCANWIDTH = 80;
static const unsigned int DEFAULT_BLOBFINDERSCANHEIGHT = 60;

 /**
@ingroup model
@defgroup model_blobfinder Blobfinder model

The blobfinder model simulates a color-blob-finding vision device,
like a CMUCAM2, or the ACTS image processing software. It can track
areas of color in a simulated 2D image, giving the location and size
of the color 'blobs'. Multiple colors can be tracked at once; they are
separated into channels, so that e.g. all red objects are tracked as
channel one, blue objects in channel two, etc. The color associated
with each channel is configurable.

<h2>Worldfile properties</h2>

@par Summary and default values

@verbatim
ptz(
  # blobfinder MUST be a child of a PTZ model
  blobfinder
  (
    # blobfinder properties
    colors_count 6
    colors ["red" "green" "blue" "cyan" "yellow" "magenta" ]
    range 8.0
    ptz[0 0 60.0]
    image[80 60]

    # model properties
    size3 [0 0 0]
  )
)
@endverbatim

@par Details
- colors_count int
  - number of colors being tracked
- colors [ string ... ]
  - define the colors detected in each channel, using color names from the 
X11-style color database 
   The number of strings should match colors_count.
- image [int int]
  - [width height]
  - dimensions of the image in pixels. This determines the blobfinder's 
    resolution
- ptz [float float float]
   - [pan_angle tilt_angle zoom_angle] 
   - control the panning, tilt and fov angle (zoom) of the blobfinder. Tilt 
angle currently has no effect.
- range float
   - maximum range of the sensor in meters.
 */


StgModelBlobfinder::StgModelBlobfinder( StgWorld* world, 
                              StgModel* parent,
                              stg_id_t id,
                              char* typestr )
  : StgModel( world, parent, id, typestr )
{
  PRINT_DEBUG2( "Constructing StgModelBlobfinder %d (%s)\n", 
                id, typestr );

  scan_width = DEFAULT_BLOBFINDERSCANWIDTH;
  scan_height = DEFAULT_BLOBFINDERSCANHEIGHT;
  fov = DEFAULT_BLOBFINDERFOV;
  range = DEFAULT_BLOBFINDERRANGE;

  ClearBlocks();
  
  blobs = g_array_new( false, true, sizeof(stg_blobfinder_blob_t));

  // leave the color filter array empty initally - this tracks all colors
  colors = g_array_new( false, true, sizeof(stg_color_t) );  
}


StgModelBlobfinder::~StgModelBlobfinder( void )
{
  if( blobs )
    g_array_free( blobs, true );
  
  if( colors )
    g_array_free( colors, true );
}

static bool blob_match( StgBlock* testblock, 
                        StgModel* finder,
                        const void* dummy )
{ 
  return( ! finder->IsRelated( testblock->Model() ));
}       


static bool ColorMatchIgnoreAlpha( stg_color_t a, stg_color_t b )
{
  return( (a & 0x00FFFFFF) == (b & 0x00FFFFFF ) );
}

void StgModelBlobfinder::StgModelBlobfinder::AddColor( stg_color_t col )
{
  g_array_append_val( colors, col );
}

/** Stop tracking blobs with this color */
void StgModelBlobfinder::RemoveColor( stg_color_t col )
{
  for( unsigned int i=0; i<colors->len; i++ )
    if( col ==  g_array_index( colors, stg_color_t, i ) )      
      g_array_remove_index_fast( colors, i );
}

/** Stop tracking all colors. Call this to clear the defaults, then
    add colors individually with AddColor(); */
void StgModelBlobfinder::RemoveAllColors()
{
  g_array_set_size( colors, 0 );
}

void StgModelBlobfinder::Load( void )
{  
  StgModel::Load(); 
  
  Worldfile* wf = world->GetWorldFile();
  
  scan_width = (int)wf->ReadTupleFloat( id, "image", 0, scan_width );
  scan_height= (int)wf->ReadTupleFloat( id, "image", 1, scan_height );
  range = wf->ReadFloat( id, "range", range );
  fov = wf->ReadAngle( id, "fov", fov );
  pan = wf->ReadAngle( id, "pan", pan );
  
  if( wf->PropertyExists( id, "colors" ) )
    {
      RemoveAllColors(); // empty the color list to start from scratch
      
      unsigned int count = wf->ReadFloat( id, "colors_count", 0 );
      
      for( unsigned int c=0; c<count; c++ )
        {
          const char* colorstr = 
            wf->ReadTupleString( id, "colors", c, NULL );
          
          if( ! colorstr )
            break;
          else
            AddColor( stg_lookup_color( colorstr ));
        }
    }    
}


void StgModelBlobfinder::Update( void )
{     
  StgModel::Update();
  
  // generate a scan for post-processing into a blob image
  
  stg_raytrace_sample_t* samples = new stg_raytrace_sample_t[scan_width];

  Raytrace( pan, range, fov, blob_match, NULL, samples, scan_width );

  
  // now the colors and ranges are filled in - time to do blob detection
  double yRadsPerPixel = fov / scan_height; 

  g_array_set_size( blobs, 0 );

  // scan through the samples looking for color blobs
  for(unsigned int s=0; s < scan_width; s++ )
    {
      if( samples[s].block == NULL  )
        continue; // we saw nothing
      
      //if( samples[s].block->Color() != 0xFFFF0000 )
      //continue; // we saw nothing
      
      unsigned int blobleft = s;
      stg_color_t blobcol = samples[s].block->Color();
      
      //printf( "blob start %d color %X\n", blobleft, blobcol );
      
      // 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( s < scan_width && samples[s].block && 
             ColorMatchIgnoreAlpha( samples[s].block->Color(), blobcol) )
        {
          //printf( "%u blobcol %X block %p %s color %X\n", s, blobcol, 
samples[s].block, samples[s].block->Model()->Token(), samples[s].block->Color() 
);
          s++;
        }
            
      unsigned int blobright = s-1;
      
      //if we have color filters in place, check to see if we're looking for 
this color
      if( colors->len )
        {
          bool found = false;
          
          for( unsigned int c=0; c<colors->len; c++ )
            if( ColorMatchIgnoreAlpha( blobcol, g_array_index( colors, 
stg_color_t, c )))
              {
                found = true;
                break;
              }
          if( ! found )
            continue; // continue scanning array for next blob
        }

      //printf( "blob end %d %X\n", blobright, blobcol );
      
      double robotHeight = 0.6; // meters

      // find the average range to the blob;
      stg_meters_t range = 0;
      for( unsigned int t=blobleft; t<=blobright; t++ )
        range += samples[t].range;
      range /= blobright-blobleft + 1;

      double startyangle = atan2( robotHeight/2.0, range );
      double endyangle = -startyangle;
      int blobtop = scan_height/2 - (int)(startyangle/yRadsPerPixel);
      int blobbottom = scan_height/2 -(int)(endyangle/yRadsPerPixel);
      
      blobtop = MIN( blobtop, (int)scan_height );
      blobbottom = MIN( blobbottom, (int)scan_height );

      // fill in an array entry for this blob
      stg_blobfinder_blob_t blob;
      memset( &blob, 0, sizeof(blob) );      
      blob.color = blobcol;
      blob.left = blobleft;
      blob.top = blobtop;
      blob.right = blobright;
      blob.bottom = blobbottom;
      blob.range = range;
      
      //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 );
    }
  
  delete [] samples;

  data_dirty = true;
}


void StgModelBlobfinder::Startup(  void )
{ 
  StgModel::Startup();
  
  PRINT_DEBUG( "blobfinder startup" );
  
  // start consuming power
  SetWatts( DEFAULT_BLOBFINDERWATTS );
}

void StgModelBlobfinder::Shutdown( void )
{ 
  
  PRINT_DEBUG( "blobfinder shutdown" );
  
  // stop consuming power
  SetWatts( 0 );
  
  // clear the data - this will unrender it too
  if( blobs )
    g_array_set_size( blobs, 0 );
  
  StgModel::Shutdown();
}

void StgModelBlobfinder::DataVisualize( void )
{
 if( debug )
    {
      // draw the FOV
      GLUquadric* quadric = gluNewQuadric();
      
      PushColor( 0,0,0,0.2  );
      
      gluQuadricDrawStyle( quadric, GLU_SILHOUETTE );
      //glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
      gluPartialDisk( quadric,
                      0, 
                      range,
                      20, // slices     
                      1, // loops
                      rtod( M_PI/2.0 + fov/2.0 - pan), // start angle
                      rtod(-fov) ); // sweep angle
      
      gluDeleteQuadric( quadric );
      PopColor();
    }

 if( subs < 1 )
   return;

  glPushMatrix();

  // return to global rotation frame
  stg_pose_t gpose = GetGlobalPose();
  glRotatef( 180 + rtod(-gpose.a),0,0,1 );
  
  // place the "screen" a little away from the robot
  glTranslatef( 0.5, 0.5, 1.0 );

  // convert blob pixels to meters scale - arbitrary
  glScalef( 0.025, 0.025, 1 );

  // draw a white screen with a black border
  glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
  PushColor( 0xFFFFFFFF );
  glRectf( 0,0, scan_width, scan_height );
  PopColor();

  glTranslatef(0,0,0.01 );

  glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
  PushColor( 0xFF000000 );
  glRectf( 0,0, scan_width, scan_height );
  PopColor();

  // draw the blobs on the screen
  glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
  for( unsigned int s=0; s<blobs->len; s++ )
    {
      stg_blobfinder_blob_t* b = 
        &g_array_index( blobs, stg_blobfinder_blob_t, s);
      
      PushColor( b->color );
      glRectf( b->left, b->top, b->right, b->bottom );

      //printf( "%u l %u t%u r %u b %u\n", s, b->left, b->top, b->right, 
b->bottom );
      PopColor();
    }

  glPopMatrix();

}




-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit

Reply via email to