stage.hh

Go to the documentation of this file.
00001 #ifndef STG_H
00002 #define STG_H
00003 /*
00004  *  Stage : a multi-robot simulator.  Part of the Player Project
00005  * 
00006  *  Copyright (C) 2001-2007 Richard Vaughan, Brian Gerkey, Andrew
00007  *  Howard
00008  *
00009  *  This program is free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  This program is distributed in the hope that it will be useful,
00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *  GNU General Public License for more details.
00018  *
00019  *  You should have received a copy of the GNU General Public License
00020  *  along with this program; if not, write to the Free Software
00021  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022  *
00023  */
00024 
00025 /* File: stage.h
00026  * Desc: External header file for the Stage library
00027  * Author: Richard Vaughan (vaughan@sfu.ca) 
00028  * Date: 1 June 2003
00029  * CVS: $Id: stage.hh,v 1.15 2008-04-01 23:57:41 rtv Exp $
00030  */
00031 
00046 
00047 #include <unistd.h>
00048 #include <stdint.h> // for portable int types eg. uint32_t
00049 #include <assert.h>
00050 #include <math.h>
00051 #include <stdlib.h>
00052 #include <stdio.h>
00053 #include <string.h>
00054 #include <sys/types.h>
00055 #include <sys/time.h>
00056 
00057 // we use GLib's data structures extensively. Perhaps we'll move to
00058 // C++ STL types to lose this dependency one day.
00059 #include <glib.h> 
00060 
00061 // FLTK Gui includes
00062 #include <FL/Fl.H>
00063 #include <FL/Fl_Box.H>
00064 #include <FL/Fl_Double_Window.H>
00065 #include <FL/Fl_Gl_Window.H>
00066 #include <FL/Fl_Menu_Bar.H>
00067 #include <FL/Fl_Menu_Button.H>
00068 #include <FL/Fl_Value_Slider.H>
00069 #include <FL/Fl_Window.H>
00070 #include <FL/Fl_Box.H>
00071 #include <FL/fl_draw.H>
00072 #include <FL/gl.h> // FLTK takes care of platform-specific GL stuff
00073 #include <FL/glut.H>
00074 
00075 #ifdef __APPLE__
00076 #include <OpenGL/glu.h>
00077 #else
00078 #include <GL/glu.h>
00079 #endif 
00080 
00081 
00083 namespace Stg 
00084 {
00086   void Init( int* argc, char** argv[] );
00087 
00089   bool InitDone(); 
00090 
00092   GHashTable* Typetable();
00093   
00094   // foreward declare
00095   class Worldfile;
00096 
00098   const char COPYRIGHT[] =                     
00099     "Copyright Richard Vaughan and contributors 2000-2008";
00100 
00102   const char AUTHORS[] =                    
00103     "Richard Vaughan, Brian Gerkey, Andrew Howard, Reed Hedges, Pooya Karimian and contributors.";
00104   
00106   const char WEBSITE[] = "http://playerstage.org";
00107   
00109   const char DESCRIPTION[] =                       
00110     "Robot simulation library\nPart of the Player Project";
00111   
00113   const char LICENSE[] = 
00114     "Stage robot simulation library\n"                  \
00115     "Copyright (C) 2000-2008 Richard Vaughan and contributors\n"    \
00116     "Part of the Player Project [http://playerstage.org]\n"     \
00117     "\n"                                \
00118     "This program is free software; you can redistribute it and/or\n"   \
00119     "modify it under the terms of the GNU General Public License\n" \
00120     "as published by the Free Software Foundation; either version 2\n"  \
00121     "of the License, or (at your option) any later version.\n"      \
00122     "\n"                                \
00123     "This program is distributed in the hope that it will be useful,\n" \
00124     "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"  \
00125     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"   \
00126     "GNU General Public License for more details.\n"            \
00127     "\n"                                \
00128     "You should have received a copy of the GNU General Public License\n" \
00129     "along with this program; if not, write to the Free Software\n" \
00130     "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\n" \
00131     "\n"                                \
00132     "The text of the license may also be available online at\n"     \
00133     "http://www.gnu.org/licenses/old-licenses/gpl-2.0.html\n";
00134   
00137   const uint32_t TOKEN_MAX = 64;
00138 
00141   const double thousand = 1e3;
00142 
00145   const double million = 1e6;
00146 
00149   const double billion = 1e9;
00150 
00153   inline double rtod( double r ){ return( r*180.0/M_PI ); }
00154   
00157   inline double dtor( double d ){ return( d*M_PI/180.0 ); }
00158   
00161   inline double normalize( double a ){ return( atan2(sin(a), cos(a)));}
00162   
00165   inline int sgn( int a){ return( a<0 ? -1 : 1); }
00166   
00169   inline double sgn( double a){ return( a<0 ? -1.0 : 1.0); }
00170   
00171   // forward declare
00172   class StgModel;
00173   
00176   typedef enum {
00177     STG_IMAGE_FORMAT_PNG,
00178     STG_IMAGE_FORMAT_JPG
00179   } stg_image_format_t;
00180   
00183   enum { FiducialNone = 0 };
00184 
00187   typedef uint32_t stg_id_t;
00188 
00191   typedef double stg_meters_t;
00192 
00195   typedef double stg_radians_t;
00196 
00198   typedef struct timeval stg_time_t;
00199 
00201   typedef unsigned long stg_msec_t;
00202 
00204   typedef uint64_t stg_usec_t;
00205 
00207   typedef double stg_kg_t; // Kilograms (mass)
00208 
00210   typedef double stg_joules_t;
00211 
00213   typedef double stg_watts_t; 
00214 
00216   typedef uint32_t stg_bool_t;
00217 
00218   //typedef double stg_friction_t;
00219 
00221   typedef uint32_t stg_color_t;
00222 
00224   stg_color_t stg_color_pack( double r, double g, double b, double a );
00225 
00227   void stg_color_unpack( stg_color_t col, 
00228              double* r, double* g, double* b, double* a );
00229 
00232   //typedef int stg_obstacle_return_t;
00233 
00236   //typedef int stg_blob_return_t;
00237 
00239   //typedef int stg_fiducial_return_t;
00240 
00241   //typedef int stg_ranger_return_t;
00242   
00243   //typedef enum { STG_GRIP_NO = 0, STG_GRIP_YES } stg_gripper_return_t;
00244   
00246   typedef struct 
00247   {
00248     stg_meters_t x, y, z;
00249   } stg_size_t;
00250   
00252   typedef struct
00253   {
00254     stg_meters_t x, y, z; //< location in 3 axes
00255     stg_radians_t a; //< rotation about the z axis. 
00256   } stg_pose_t;
00257   
00259   typedef stg_pose_t stg_velocity_t;  
00260 
00263   typedef struct
00264   {
00265     stg_pose_t pose; //< position
00266     stg_size_t size; //< extent
00267   } stg_geom_t;
00268   
00270   typedef struct
00271   {
00272     double min; //< smallest value in range
00273     double max; //< largest value in range
00274   } stg_bounds_t;
00275   
00277   typedef struct
00278   {
00279     stg_bounds_t x; //< volume extent along x axis
00280     stg_bounds_t y; //< volume extent along y axis
00281     stg_bounds_t z; //< volume extent along z axis 
00282   } stg_bounds3d_t;
00283 
00286   typedef struct
00287   {
00288     stg_meters_t min; //< smallest value in range
00289     stg_meters_t max; //< largest value in range
00290   } stg_range_bounds_t;
00291   
00293   typedef struct
00294   {
00295     stg_bounds_t x, y, z;
00296   } stg_bbox3d_t;
00297 
00299   typedef struct
00300   {
00301     stg_bounds_t range; //< min and max range of sensor
00302     stg_radians_t angle; //< width of viewing angle of sensor
00303   } stg_fov_t;
00304 
00305   
00307   typedef struct
00308   {
00309     stg_meters_t x, y;
00310   } stg_point_t;
00311   
00313   typedef struct
00314   {
00315     float x, y, z;
00316   } stg_vertex_t;
00317   
00319   typedef struct
00320   {
00321     float x, y, z, r, g, b, a;    
00322   } stg_colorvertex_t;
00323 
00325   typedef struct
00326   {
00327     stg_meters_t x, y, z;
00328   } stg_point3_t;
00329   
00332   typedef struct
00333   {
00334     int32_t x,y;
00335   } stg_point_int_t;
00336   
00340   stg_point_t* stg_points_create( size_t count );
00341 
00343   void stg_points_destroy( stg_point_t* pts );
00344   
00347   stg_point_t* stg_unit_square_points_create();
00348 
00349 
00352   typedef int(*stg_line3d_func_t)(int32_t x, int32_t y, int32_t z,
00353                   void* arg );
00354 
00355 
00360   int stg_line_3d( int32_t x, int32_t y, int32_t z,
00361            int32_t dx, int32_t dy, int32_t dz,
00362            stg_line3d_func_t visit_voxel,
00363            void* arg );
00364 
00367   int stg_polygon_3d( stg_point_int_t* pts, 
00368               unsigned int pt_count, 
00369               stg_line3d_func_t visit_voxel, 
00370               void* arg );
00371   
00372 
00373   const uint32_t STG_MOVE_TRANS = (1 << 0);
00374   const uint32_t STG_MOVE_ROT   = (1 << 1);
00375   const uint32_t STG_MOVE_SCALE = (1 << 2);
00376   
00377   typedef uint32_t stg_movemask_t;
00378 
00379   const char STG_MP_PREFIX[] =             "_mp_";
00380   const char STG_MP_POSE[] =               "_mp_pose";
00381   const char STG_MP_VELOCITY[] =           "_mp_velocity";
00382   const char STG_MP_GEOM[] =               "_mp_geom";
00383   const char STG_MP_COLOR[] =              "_mp_color";
00384   const char STG_MP_WATTS[] =              "_mp_watts";
00385   const char STG_MP_FIDUCIAL_RETURN[] =    "_mp_fiducial_return";
00386   const char STG_MP_LASER_RETURN[] =       "_mp_laser_return";
00387   const char STG_MP_OBSTACLE_RETURN[] =    "_mp_obstacle_return";
00388   const char STG_MP_RANGER_RETURN[] =      "_mp_ranger_return";
00389   const char STG_MP_GRIPPER_RETURN[] =     "_mp_gripper_return";
00390   const char STG_MP_MASS[] =               "_mp_mass";
00391   
00392 
00394   typedef enum 
00395     {
00396       LaserTransparent, 
00397       LaserVisible, 
00398       LaserBright  
00399     } stg_laser_return_t;
00400 
00401 
00402 namespace Draw
00403 {
00404   typedef struct {
00405     double x, y, z;
00406   } vertex_t;
00407 
00408   typedef struct {
00409     vertex_t min, max;
00410   } bounds3_t;
00411   
00412   typedef enum {
00413     STG_D_DRAW_POINTS,
00414     STG_D_DRAW_LINES,
00415     STG_D_DRAW_LINE_STRIP,
00416     STG_D_DRAW_LINE_LOOP,
00417     STG_D_DRAW_TRIANGLES,
00418     STG_D_DRAW_TRIANGLE_STRIP,
00419     STG_D_DRAW_TRIANGLE_FAN,
00420     STG_D_DRAW_QUADS,
00421     STG_D_DRAW_QUAD_STRIP,
00422     STG_D_DRAW_POLYGON,
00423     STG_D_PUSH,
00424     STG_D_POP,
00425     STG_D_ROTATE,
00426     STG_D_TRANSLATE,
00427   } type_t;
00428   
00430   typedef struct
00431   {
00432     type_t type;
00433   } hdr_t;
00434 
00436   typedef hdr_t push_t;
00438   typedef hdr_t pop_t;
00439   
00441   typedef struct
00442   {
00444     type_t type;
00446     size_t vert_count;
00448     vertex_t verts[]; 
00449   } draw_t;
00450   
00452   typedef struct
00453   {
00455     type_t type; 
00457     vertex_t vector;
00458   } translate_t;
00459   
00461   typedef  struct
00462   {
00464     type_t type; 
00466     vertex_t vector;
00468     stg_radians_t angle;
00469   } rotate_t;
00470 
00472   draw_t* create( type_t type,  
00473           vertex_t* verts,
00474           size_t vert_count );
00475 
00477   void destroy( draw_t* d );
00478 } // end namespace draw
00479 
00480 
00481   // MACROS ------------------------------------------------------
00482   // Some useful macros
00483   
00484   
00489   stg_color_t stg_lookup_color(const char *name);
00490 
00493   void stg_pose_sum( stg_pose_t* result, stg_pose_t* p1, stg_pose_t* p2 );
00494   
00496   stg_pose_t pose_sum( stg_pose_t p1, stg_pose_t p2 );
00497 
00498   // PRETTY PRINTING -------------------------------------------------
00499   
00501   void stg_print_err( const char* err );
00503   void stg_print_geom( stg_geom_t* geom );
00505   void stg_print_pose( stg_pose_t* pose );
00507   void stg_print_velocity( stg_velocity_t* vel );
00508   
00509   const uint32_t STG_SHOW_BLOCKS =     (1<<0);
00510   const uint32_t STG_SHOW_DATA =       (1<<1); 
00511   const uint32_t STG_SHOW_GEOM =       (1<<2);
00512   const uint32_t STG_SHOW_GRID =       (1<<3);
00513   const uint32_t STG_SHOW_OCCUPANCY =  (1<<4);
00514   const uint32_t STG_SHOW_TRAILS =     (1<<5); 
00515   const uint32_t STG_SHOW_FOLLOW =     (1<<6); 
00516   const uint32_t STG_SHOW_CLOCK =      (1<<7);
00517   const uint32_t STG_SHOW_QUADTREE =   (1<<8);
00518   const uint32_t STG_SHOW_ARROWS =     (1<<9);
00519   const uint32_t STG_SHOW_FOOTPRINT =  (1<<10);
00520   const uint32_t STG_SHOW_BLOCKS_2D =  (1<<10);
00521 
00522   // forward declare
00523   class StgWorld;
00524   class StgModel;
00525 
00526   GHashTable* stg_create_typetable();
00527 
00529   typedef StgModel* (*stg_creator_t)( StgWorld*, StgModel*, stg_id_t, char* );
00530   
00531   typedef struct 
00532   {
00533     const char* token;
00534     stg_creator_t creator_fn;
00535   } stg_typetable_entry_t;
00536 
00537 
00538   void gl_draw_grid( stg_bounds3d_t vol );
00539   void gl_pose_shift( stg_pose_t* pose );
00540   void gl_coord_shift( double x, double y, double z, double a  );
00541 
00542   class StgFlag
00543   {
00544   public:
00545     stg_color_t color;
00546     double size;
00547 
00548     StgFlag( stg_color_t color, double size );
00549     StgFlag* Nibble( double portion );
00550   };
00551   
00553   void gl_draw_string( float x, float y, float z, char *string);
00554 
00555 
00556   void stg_block_list_scale( GList* blocks, 
00557                  stg_size_t* size );
00558   void stg_block_list_destroy( GList* list );
00559 
00560 
00561   typedef int(*stg_model_callback_t)(StgModel* mod, void* user );
00562   
00563   // return val, or minval if val < minval, or maxval if val > maxval
00564   double constrain( double val, double minval, double maxval );
00565 
00566   
00569   typedef struct
00570   {
00571     stg_model_callback_t callback;
00572     void* arg;
00573   } stg_cb_t;
00574 
00575   stg_cb_t* cb_create( stg_model_callback_t callback, void* arg );
00576   void cb_destroy( stg_cb_t* cb );
00577 
00578   typedef struct
00579   {
00580     StgModel* mod;
00581     void* member;
00582     char* name;
00583     stg_model_callback_t callback_on;
00584     stg_model_callback_t callback_off;
00585     void* arg_on; // argument to callback_on
00586     void* arg_off; // argument to callback_off
00587     //int default_state; // disabled = 0
00588     //GtkAction* action; // action associated with this toggle, may be NULL
00589     char* path;
00590   } stg_property_toggle_args_t;
00591 
00592 
00593 
00595   typedef struct
00596   {
00597     stg_pose_t pose;
00598     stg_size_t size;
00599   } stg_rotrect_t; // rotated rectangle
00600 
00604   void stg_rotrects_normalize( stg_rotrect_t* rects, int num );
00605 
00611   int stg_rotrects_from_image_file( const char* filename, 
00612                     stg_rotrect_t** rects,
00613                     unsigned int* rect_count,
00614                     unsigned int* widthp, 
00615                     unsigned int* heightp );
00616 
00617   // /** matching function should return 0 iff the candidate block is
00618   //     acceptable */
00619   class StgBlock;
00620 
00621   typedef bool (*stg_block_match_func_t)(StgBlock* candidate, StgModel* finder, const void* arg );
00622 
00623   // TODO - some of this needs to be implemented, the rest junked.
00624 
00625   /*   //  -------------------------------------------------------------- */
00626 
00627   /*   // standard energy consumption of some devices in W. */
00628   /*   // */
00629   /*   // The MOTIONKG value is a hack to approximate cost of motion, as */
00630   /*   // Stage does not yet have an acceleration model. */
00631   /*   // */
00632   /* #define STG_ENERGY_COST_LASER 20.0 // 20 Watts! (LMS200 - from SICK web site) */
00633   /* #define STG_ENERGY_COST_FIDUCIAL 10.0 // 10 Watts */
00634   /* #define STG_ENERGY_COST_RANGER 0.5 // 500mW (estimate) */
00635   /* #define STG_ENERGY_COST_MOTIONKG 10.0 // 10 Watts per KG when moving  */
00636   /* #define STG_ENERGY_COST_BLOB 4.0 // 4W (estimate) */
00637 
00638   /*   typedef struct */
00639   /*   { */
00640   /*     stg_joules_t joules; // current energy stored in Joules/1000 */
00641   /*     stg_watts_t watts; // current power expenditure in mW (mJoules/sec) */
00642   /*     int charging; // 1 if we are receiving energy, -1 if we are */
00643   /*     // supplying energy, 0 if we are neither charging nor */
00644   /*     // supplying energy. */
00645   /*     stg_meters_t range; // the range that our charging probe hit a charger */
00646   /*   } stg_energy_data_t; */
00647 
00648   /*   typedef struct */
00649   /*   { */
00650   /*     stg_joules_t capacity; // maximum energy we can store (we start fully charged) */
00651   /*     stg_meters_t probe_range; // the length of our recharge probe */
00652   /*     //stg_pose_t probe_pose; // TODO - the origin of our probe */
00653 
00654   /*     stg_watts_t give_rate; // give this many Watts to a probe that hits me (possibly 0) */
00655   
00656   /*     stg_watts_t trickle_rate; // this much energy is consumed or */
00657   /*     // received by this device per second as a */
00658   /*     // baseline trickle. Positive values mean */
00659   /*     // that the device is just burning energy */
00660   /*     // stayting alive, which is appropriate */
00661   /*     // for most devices. Negative values mean */
00662   /*     // that the device is receiving energy */
00663   /*     // from the environment, simulating a */
00664   /*     // solar cell or some other ambient energy */
00665   /*     // collector */
00666 
00667   /*   } stg_energy_config_t; */
00668 
00669 
00670   /*   // BLINKENLIGHT ------------------------------------------------------------ */
00671 
00672   /*   // a number of milliseconds, used for example as the blinkenlight interval */
00673   /* #define STG_LIGHT_ON UINT_MAX */
00674   /* #define STG_LIGHT_OFF 0 */
00675 
00676   //typedef int stg_interval_ms_t;
00677 
00678 
00679   /*   // TOKEN ----------------------------------------------------------------------- */
00680   /*   // token stuff for parsing worldfiles - this may one day replace
00681        the worldfile c++ code */
00682 
00683   /* #define CFG_OPEN '(' */
00684   /* #define CFG_CLOSE ')' */
00685   /* #define STR_OPEN '\"' */
00686   /* #define STR_CLOSE '\"' */
00687   /* #define TPL_OPEN '[' */
00688   /* #define TPL_CLOSE ']' */
00689 
00690   /*   typedef enum { */
00691   /*     STG_T_NUM = 0, */
00692   /*     STG_T_BOOLEAN, */
00693   /*     STG_T_MODELPROP, */
00694   /*     STG_T_WORLDPROP, */
00695   /*     STG_T_NAME, */
00696   /*     STG_T_STRING, */
00697   /*     STG_T_KEYWORD, */
00698   /*     STG_T_CFG_OPEN, */
00699   /*     STG_T_CFG_CLOSE, */
00700   /*     STG_T_TPL_OPEN, */
00701   /*     STG_T_TPL_CLOSE, */
00702   /*   } stg_token_type_t; */
00703 
00704 
00705 
00706 
00707   /* typedef struct stg_token  */
00708   /* { */
00709   /*   char* token; ///< the text of the token */
00710   /*   stg_token_type_t type; ///< the type of the token */
00711   /*   unsigned int line; ///< the line on which the token appears */
00712   
00713   /*   struct stg_token* next; ///< linked list support */
00714   /*   struct stg_token* child; ///< tree support */
00715   
00716   /* } stg_token_t; */
00717 
00718   /*   stg_token_t* stg_token_next( stg_token_t* tokens ); */
00719   /*   /// print [token] formatted for a human reader, with a string [prefix] */
00720   /*   void stg_token_print( char* prefix,  stg_token_t* token ); */
00721 
00722   /*   /// print a token array suitable for human reader */
00723   /*   void stg_tokens_print( stg_token_t* tokens ); */
00724   /*   void stg_tokens_free( stg_token_t* tokens ); */
00725   
00726   /*   /// create a new token structure from the arguments */
00727   /*   stg_token_t* stg_token_create( const char* token, stg_token_type_t type, int line ); */
00728 
00729   /*   /// add a token to a list */
00730   /*   stg_token_t* stg_token_append( stg_token_t* head, */
00731   /*                 char* token, stg_token_type_t type, int line ); */
00732 
00733   /*   const char* stg_token_type_string( stg_token_type_t type ); */
00734 
00735   /*   const char* stg_model_type_string( stg_model_type_t type ); */
00736   
00737   /*   //  functions for parsing worldfiles */
00738   /*   stg_token_t* stg_tokenize( FILE* wf ); */
00739   /*   //StgWorld* sc_load_worldblock( stg_client_t* cli, stg_token_t** tokensptr ); */
00740   /*   //stg_model_t* sc_load_modelblock( StgWorld* world, stg_model_t* parent, */
00741   /*   //              stg_token_t** tokensptr ); */
00742 
00743 
00744 
00745 
00746   //#ifdef __cplusplus
00747   //}
00748   //#endif 
00749 
00750 
00751   // list iterator macros
00752 #define LISTFUNCTION( LIST, TYPE, FUNC ) for( GList* it=LIST; it; it=it->next ) FUNC((TYPE)it->data);
00753  
00754 #define LISTMETHOD( LIST, TYPE, METHOD ) for( GList* it=LIST; it; it=it->next ) ((TYPE)it->data)->METHOD();
00755  
00756 #define LISTFUNCTIONARG( LIST, TYPE, FUNC, ARG ) for( GList* it=LIST; it; it=it->next ) FUNC((TYPE)it->data, ARG);
00757  
00758 #define LISTMETHODARG( LIST, TYPE, METHOD, ARG ) for( GList* it=LIST; it; it=it->next ) ((TYPE)it->data)->METHOD(ARG);
00759  
00760 
00761   // Error macros - output goes to stderr
00762 #define PRINT_ERR(m) fprintf( stderr, "\033[41merr\033[0m: "m" (%s %s)\n", __FILE__, __FUNCTION__)
00763 #define PRINT_ERR1(m,a) fprintf( stderr, "\033[41merr\033[0m: "m" (%s %s)\n", a, __FILE__, __FUNCTION__)    
00764 #define PRINT_ERR2(m,a,b) fprintf( stderr, "\033[41merr\033[0m: "m" (%s %s)\n", a, b, __FILE__, __FUNCTION__) 
00765 #define PRINT_ERR3(m,a,b,c) fprintf( stderr, "\033[41merr\033[0m: "m" (%s %s)\n", a, b, c, __FILE__, __FUNCTION__)
00766 #define PRINT_ERR4(m,a,b,c,d) fprintf( stderr, "\033[41merr\033[0m: "m" (%s %s)\n", a, b, c, d, __FILE__, __FUNCTION__)
00767 #define PRINT_ERR5(m,a,b,c,d,e) fprintf( stderr, "\033[41merr\033[0m: "m" (%s %s)\n", a, b, c, d, e, __FILE__, __FUNCTION__)
00768 
00769   // Warning macros
00770 #define PRINT_WARN(m) printf( "\033[44mwarn\033[0m: "m" (%s %s)\n", __FILE__, __FUNCTION__)
00771 #define PRINT_WARN1(m,a) printf( "\033[44mwarn\033[0m: "m" (%s %s)\n", a, __FILE__, __FUNCTION__)    
00772 #define PRINT_WARN2(m,a,b) printf( "\033[44mwarn\033[0m: "m" (%s %s)\n", a, b, __FILE__, __FUNCTION__) 
00773 #define PRINT_WARN3(m,a,b,c) printf( "\033[44mwarn\033[0m: "m" (%s %s)\n", a, b, c, __FILE__, __FUNCTION__)
00774 #define PRINT_WARN4(m,a,b,c,d) printf( "\033[44mwarn\033[0m: "m" (%s %s)\n", a, b, c, d, __FILE__, __FUNCTION__)
00775 #define PRINT_WARN5(m,a,b,c,d,e) printf( "\033[44mwarn\033[0m: "m" (%s %s)\n", a, b, c, d, e, __FILE__, __FUNCTION__)
00776 
00777   // Message macros
00778 #ifdef DEBUG
00779 #define PRINT_MSG(m) printf( "Stage: "m" (%s %s)\n", __FILE__, __FUNCTION__)
00780 #define PRINT_MSG1(m,a) printf( "Stage: "m" (%s %s)\n", a, __FILE__, __FUNCTION__)    
00781 #define PRINT_MSG2(m,a,b) printf( "Stage: "m" (%s %s)\n", a, b, __FILE__, __FUNCTION__) 
00782 #define PRINT_MSG3(m,a,b,c) printf( "Stage: "m" (%s %s)\n", a, b, c, __FILE__, __FUNCTION__)
00783 #define PRINT_MSG4(m,a,b,c,d) printf( "Stage: "m" (%s %s)\n", a, b, c, d, __FILE__, __FUNCTION__)
00784 #define PRINT_MSG5(m,a,b,c,d,e) printf( "Stage: "m" (%s %s)\n", a, b, c, d, e,__FILE__, __FUNCTION__)
00785 #else
00786 #define PRINT_MSG(m) printf( "Stage: "m"\n" )
00787 #define PRINT_MSG1(m,a) printf( "Stage: "m"\n", a)
00788 #define PRINT_MSG2(m,a,b) printf( "Stage: "m"\n,", a, b )
00789 #define PRINT_MSG3(m,a,b,c) printf( "Stage: "m"\n", a, b, c )
00790 #define PRINT_MSG4(m,a,b,c,d) printf( "Stage: "m"\n", a, b, c, d )
00791 #define PRINT_MSG5(m,a,b,c,d,e) printf( "Stage: "m"\n", a, b, c, d, e )
00792 #endif
00793 
00794   // DEBUG macros
00795 #ifdef DEBUG
00796 #define PRINT_DEBUG(m) printf( "debug: "m" (%s %s)\n", __FILE__, __FUNCTION__)
00797 #define PRINT_DEBUG1(m,a) printf( "debug: "m" (%s %s)\n", a, __FILE__, __FUNCTION__)    
00798 #define PRINT_DEBUG2(m,a,b) printf( "debug: "m" (%s %s)\n", a, b, __FILE__, __FUNCTION__) 
00799 #define PRINT_DEBUG3(m,a,b,c) printf( "debug: "m" (%s %s)\n", a, b, c, __FILE__, __FUNCTION__)
00800 #define PRINT_DEBUG4(m,a,b,c,d) printf( "debug: "m" (%s %s)\n", a, b, c ,d, __FILE__, __FUNCTION__)
00801 #define PRINT_DEBUG5(m,a,b,c,d,e) printf( "debug: "m" (%s %s)\n", a, b, c ,d, e, __FILE__, __FUNCTION__)
00802 #else
00803 #define PRINT_DEBUG(m)
00804 #define PRINT_DEBUG1(m,a)
00805 #define PRINT_DEBUG2(m,a,b)
00806 #define PRINT_DEBUG3(m,a,b,c)
00807 #define PRINT_DEBUG4(m,a,b,c,d)
00808 #define PRINT_DEBUG5(m,a,b,c,d,e)
00809 #endif
00810 
00811   class StgBlock;
00812   class StgModel;
00813 
00814 
00815   stg_msec_t stg_realtime();
00816   stg_msec_t stg_realtime_since_start( void );
00817 
00818 
00819 
00820   // ANCESTOR CLASS
00821 
00824   typedef int (*stg_model_callback_t)( StgModel* mod, void* user );
00825   
00826   
00828   class StgAncestor
00829   {
00830     friend class StgCanvas; // allow StgCanvas access to our private members
00831   
00832   protected:
00833     GList* children;
00834     GHashTable* child_types;
00835     char* token;
00836     bool debug;
00837 
00838   public:
00839     StgAncestor();
00840     virtual ~StgAncestor();
00841   
00842     unsigned int GetNumChildrenOfType( const char* typestr );
00843     void IncrementNumChildrenOfType( const char* typestr );
00844   
00845     virtual void AddChild( StgModel* mod );
00846     virtual void RemoveChild( StgModel* mod );
00847     virtual stg_pose_t GetGlobalPose();  
00848   
00849     const char* Token()
00850     { return this->token; }
00851   
00852     // PURE VIRTUAL - descendents must implement
00853     virtual void PushColor( stg_color_t col ) = 0;
00854     virtual void PushColor( double r, double g, double b, double a ) = 0;
00855     virtual void PopColor() = 0; // does nothing
00856   };
00857 
00858   
00859   typedef struct 
00860   {
00861     int enabled;
00862     stg_pose_t pose;
00863     stg_meters_t size; 
00864     stg_color_t color;
00865     stg_msec_t period; 
00866     double duty_cycle; 
00867   } stg_blinkenlight_t;
00868 
00869   typedef struct
00870   {
00871     uint32_t counter;
00872     GSList** lists;
00873   } stg_bigblock_t;
00874 
00875   typedef struct
00876   {
00877     StgWorld* world;
00878     StgBlock* block;
00879   } stg_render_info_t;
00880 
00881 
00882   class StgBlockGrid 
00883   {
00884   private:
00885     //stg_bigblock_t* map;
00886     GSList** cells;
00887 
00888     //GTrashStack* trashstack;  
00889     uint32_t width, height;// bwidth, bheight;
00890 
00891   public:
00892     //uint32_t numbits;
00893     StgBlockGrid( uint32_t width, uint32_t height );
00894     ~StgBlockGrid();
00895     void AddBlock( uint32_t x, uint32_t y, StgBlock* block );
00896     void RemoveBlock( uint32_t x, uint32_t y, StgBlock* block );
00897     GSList* GetList( uint32_t x, uint32_t y );
00898     void GlobalRemoveBlock( StgBlock* block );
00899     void Draw( bool drawall );
00900   
00903     //uint32_t BigBlockOccupancy( uint32_t bbx, uint32_t bby );
00904   };
00905   
00908   typedef struct
00909   {
00910     stg_pose_t pose; 
00911     stg_meters_t range; 
00912     StgBlock* block; 
00913   } stg_raytrace_sample_t;
00914 
00915 
00916   const uint32_t INTERVAL_LOG_LEN = 32;
00917   
00918   class Region;
00919   class SuperRegion;
00920 
00922   class StgWorld : public StgAncestor
00923   {
00924     friend class StgModel; // allow access to private members
00925     friend class StgBlock;
00926     friend class StgTime;
00927 
00928   private:
00929 
00930     static bool quit_all; // quit all worlds ASAP  
00931     static unsigned int next_id; //< initialized to zero, used to
00932     //allocate unique sequential world ids
00933     static int AddBlockPixel( int x, int y, int z,
00934                   stg_render_info_t* rinfo ) ; //< used as a callback by StgModel
00935 
00936     stg_usec_t real_time_next_update;
00937     stg_usec_t real_time_start;
00938   
00939     bool quit; // quit this world ASAP
00940 
00941   
00942     inline void MetersToPixels( stg_meters_t mx, stg_meters_t my, 
00943                 int32_t *px, int32_t *py );
00944     
00945     void Initialize( const char* token, 
00946              stg_msec_t interval_sim, 
00947              stg_msec_t interval_real,
00948              double ppm );
00949     //       double width,
00950     //       double height );
00951   
00952 
00953     virtual void PushColor( stg_color_t col ) { /* do nothing */  };
00954     virtual void PushColor( double r, double g, double b, double a ) { /* do nothing */  };
00955     virtual void PopColor(){ /* do nothing */  };
00956 
00957     stg_usec_t real_time_now;
00958  
00960     stg_usec_t quit_time; 
00961  
00962     bool destroy;
00963 
00964     stg_id_t id;
00965 
00966     GHashTable* models_by_id; 
00967     GHashTable* models_by_name; 
00968     GList* velocity_list; 
00969 
00970     stg_usec_t sim_time; 
00971     stg_usec_t wall_last_update; 
00972 
00973     long unsigned int updates; 
00974   
00975     bool dirty; 
00976 
00977     stg_usec_t interval_sleep_max;
00978     stg_usec_t interval_sim; 
00979 
00980     stg_usec_t interval_log[INTERVAL_LOG_LEN];
00981   
00982     int total_subs; 
00983     double ppm; 
00984 
00985     bool paused; 
00986 
00987     GList* update_list; //< the descendants that need Update() called
00988     void AddModelName( StgModel* mod );  
00989 
00990     void StartUpdatingModel( StgModel* mod );
00991     void StopUpdatingModel( StgModel* mod );
00992   
00993     //void MapBlock( StgBlock* block );
00994 
00995     SuperRegion* CreateSuperRegion( int32_t x, int32_t y );
00996     void DestroySuperRegion( SuperRegion* sr );
00997 
00998     void Raytrace( stg_pose_t pose,              
00999            stg_meters_t range,
01000            stg_block_match_func_t func,
01001            StgModel* finder,
01002            const void* arg,
01003            stg_raytrace_sample_t* sample );
01004   
01005     void Raytrace( stg_pose_t pose,              
01006            stg_meters_t range,
01007            stg_radians_t fov,
01008            stg_block_match_func_t func,
01009            StgModel* finder,
01010            const void* arg,
01011            stg_raytrace_sample_t* samples,
01012            uint32_t sample_count );
01013   
01014     void RemoveBlock( int x, int y, StgBlock* block );
01015     //{ }//bgrid->RemoveBlock( x, y, block ); };
01016   
01017   protected:
01018     stg_usec_t interval_real;   
01019 
01020     GHashTable* superregions;
01021 
01022     GList* ray_list;
01023     // store rays traced for debugging purposes
01024     void RecordRay( double x1, double y1, double x2, double y2 );
01025     Worldfile* wf; 
01026     bool graphics;
01027     stg_bounds3d_t extent;
01028     
01030     void Extend( stg_point3_t pt );
01031     
01032     //GHashTable* blocks;
01033     GArray lines;
01034 
01035   public:
01036 
01037     StgWorld();
01038   
01039     StgWorld( const char* token, 
01040           stg_msec_t interval_sim, 
01041           stg_msec_t interval_real,
01042           double ppm ); 
01043   
01044     virtual ~StgWorld();
01045     
01046     stg_usec_t SimTimeNow(void){ return sim_time;} ;
01047     stg_usec_t RealTimeNow(void);
01048     stg_usec_t RealTimeSinceStart(void);
01049     void PauseUntilNextUpdateTime(void);
01050     void IdleUntilNextUpdateTime( int (*idler)(void) );
01051 
01052     void AddBlock( StgBlock* block );
01053     void RemoveBlock( StgBlock* block );
01054   
01055     stg_usec_t GetSimInterval(){ return interval_sim; }; 
01056     
01057 
01058     Worldfile* GetWorldFile(){ return wf; };
01059   
01060     virtual void Load( const char* worldfile_path );
01061     virtual void Reload();
01062     virtual void Save();
01063     virtual bool Update(void);
01064     virtual bool RealTimeUpdate(void);
01065     virtual bool RealTimeUpdateWithIdler( int (*idler)(void) );
01066 
01067     virtual void AddModel( StgModel* mod );
01068     virtual void RemoveModel( StgModel* mod );
01069   
01070     void Start(){ paused = false; };
01071     void Stop(){ paused = true; };
01072     void TogglePause(){ paused = !paused; };
01073     bool TestQuit(){ return( quit || quit_all );  }
01074     void Quit(){ quit = true; }
01075     void QuitAll(){ quit_all = true; }
01076     void CancelQuit(){ quit = false; }
01077     void CancelQuitAll(){ quit_all = false; }
01078   
01079     double Resolution(){ return ppm; };
01080   
01081     StgModel* GetModel( const stg_id_t id );
01082     StgModel* GetModel( const char* name );
01083     
01084 
01085     GList* GetRayList(){ return ray_list; };
01086     void ClearRays();
01087     
01088     void ClockString( char* str, size_t maxlen );
01089 
01090     stg_bounds3d_t GetExtent(){ return extent; };  
01091         
01092     void ForEachModel( GHFunc func, void* arg )
01093     { g_hash_table_foreach( models_by_id, func, arg ); };
01094 
01095     long unsigned int GetUpdateCount()
01096     { return updates; }
01097   };
01098 
01099 
01100   typedef struct {
01101     stg_pose_t pose;
01102     stg_color_t color;
01103     stg_usec_t time;
01104   } stg_trail_item_t;
01105   
01106   typedef int ctrlinit_t( StgModel* mod );
01107   //typedef void ctrlupdate_t( StgModel* mod );
01108 
01109   // MODEL CLASS
01110   class StgModel : public StgAncestor
01111   {
01112     friend class StgAncestor;
01113     friend class StgWorld;
01114     friend class StgWorldGui;
01115     friend class StgCanvas;
01116 
01117   protected:
01118 
01119     const char* typestr;
01120     stg_pose_t pose;
01121     stg_velocity_t velocity;    
01122     stg_watts_t watts; //< power consumed by this model
01123     stg_color_t color;
01124     stg_kg_t mass;
01125     stg_geom_t geom;
01126     stg_laser_return_t laser_return;
01127     int obstacle_return;
01128     int blob_return;
01129     int gripper_return;
01130     int ranger_return;
01131     int fiducial_return;
01132     int fiducial_key;
01133     int boundary;
01134     stg_meters_t map_resolution;
01135     stg_bool_t stall;
01136   
01138     char* say_string; 
01139 
01140     bool on_velocity_list;
01141 
01142     int gui_nose;
01143     int gui_grid;
01144     int gui_outline;
01145     int gui_mask;
01146   
01147     StgModel* parent; //< the model that owns this one, possibly NULL
01148   
01152     GData* props;
01153   
01157     GHashTable* callbacks;
01158   
01159     int subs;     //< the number of subscriptions to this model
01160   
01161     stg_usec_t interval; //< time between updates in ms
01162     stg_usec_t last_update; //< time of last update in ms
01163   
01164     stg_bool_t disabled; //< if non-zero, the model is disabled
01165    
01166     GList* d_list;    
01167     GList* blocks; //< list of stg_block_t structs that comprise a body
01168   
01169     GArray* trail;
01170   
01171     //  stg_trail_item_t* history; 
01172 
01173     bool body_dirty; //< iff true, regenerate block display list before redraw
01174     bool data_dirty; //< iff true, regenerate data display list before redraw
01175 
01176     stg_pose_t global_pose;
01177 
01178     bool gpose_dirty; //< set this to indicate that global pose may have
01179     //changed
01180 
01181     bool data_fresh; 
01182 
01183 
01184 
01185 
01186     stg_id_t id; // globally unique ID used as hash table key and
01187     // worldfile section identifier
01188 
01189     StgWorld* world; // pointer to the world in which this model exists
01190 
01191     StgModel* TestCollision( stg_pose_t* pose, 
01192                  double* hitx, double* hity );
01193 
01194 
01195     void Map();
01196     void UnMap();
01197 
01198     void MapWithChildren();
01199     void UnMapWithChildren();
01200 
01201     int TreeToPtrArray( GPtrArray* array );
01202   
01203 
01204     // raytraces from the point and heading identified by pose, in local coords
01205     void Raytrace( stg_pose_t pose,
01206            stg_meters_t range, 
01207            stg_block_match_func_t func,
01208            const void* arg,
01209            stg_raytrace_sample_t* sample );
01210 
01211     // this version raytraces from our local origin in the direction [angle]
01212     void Raytrace( stg_radians_t angle, 
01213            stg_meters_t range, 
01214            stg_block_match_func_t func,
01215            const void* arg,
01216            stg_raytrace_sample_t* sample );
01217 
01218     // raytraces from the point and heading identified by pose, in local coords
01219     void Raytrace( stg_pose_t pose,
01220            stg_meters_t range, 
01221            stg_radians_t fov, 
01222            stg_block_match_func_t func,
01223            const void* arg,
01224            stg_raytrace_sample_t* samples,
01225            uint32_t sample_count );
01226 
01227     // this version raytraces from our local origin in the direction [angle]
01228     void Raytrace( stg_radians_t angle, 
01229            stg_meters_t range, 
01230            stg_radians_t fov, 
01231            stg_block_match_func_t func,
01232            const void* arg,
01233            stg_raytrace_sample_t* samples,
01234            uint32_t sample_count );
01235 
01236   
01240     void GPoseDirtyTree();
01241 
01242     virtual void Startup();
01243     virtual void Shutdown();
01244     virtual void Update();
01245     virtual void UpdatePose();
01246     virtual void Draw( uint32_t flags );
01247 
01248     virtual void DrawBlocks();
01249 
01250     // static wrapper for DrawBlocks()
01251     static void DrawBlocks( gpointer dummykey, 
01252                 StgModel* mod, 
01253                 void* arg );
01254       
01255     virtual void DrawPicker();
01256     virtual void DataVisualize();
01257 
01258     virtual void DrawSelected(void);
01259 
01260     void DrawTrailFootprint();
01261     void DrawTrailBlocks();
01262     void DrawTrailArrows();
01263     void DrawGrid();
01264     void UpdateIfDue();
01265 
01266     /* hooks for attaching special callback functions (not used as
01267        variables) */
01268     char startup, shutdown, load, save, update;
01269     
01270     ctrlinit_t* initfunc;
01271     //ctrlupdate_t* updatefunc;
01272 
01273     GList* flag_list;
01274     
01275     GPtrArray* blinkenlights;
01276     void DrawBlinkenlights();
01277 
01278   public:
01279   
01280     // constructor
01281     StgModel( StgWorld* world, StgModel* parent, stg_id_t id, char* typestr );
01282   
01283     // destructor
01284     virtual ~StgModel();
01285 
01286     void Say( char* str );
01287   
01288     stg_id_t Id(){ return id; };
01289 
01291     virtual void Load();
01293     virtual void Save();
01294 
01296     void Init();
01297     
01298     
01299     void AddFlag(  StgFlag* flag );
01300     void RemoveFlag( StgFlag* flag );
01301     
01302     void PushFlag( StgFlag* flag );
01303     StgFlag* PopFlag();
01304 
01305     int GetFlagCount(){ return g_list_length( flag_list ); }
01306 
01307     void DrawFlagList();
01308     
01309     void AddBlinkenlight( stg_blinkenlight_t* b )
01310     {
01311       g_ptr_array_add( this->blinkenlights, b );
01312     }
01313     
01314     void ClearBlinkenlights()
01315     {
01316       g_ptr_array_set_size( this->blinkenlights, 0 );
01317     }
01318     
01319     virtual void PushColor( stg_color_t col )
01320     { world->PushColor( col ); }
01321   
01322     virtual void PushColor( double r, double g, double b, double a )
01323     { world->PushColor( r,g,b,a ); }
01324     
01325     virtual void PopColor(){ world->PopColor(); }
01326 
01327     void Enable(){ disabled = false; };
01328     void Disable(){ disabled = true; };
01329     
01330     // Load a control program for this model from an external library
01331     void LoadControllerModule( char* lib );
01332 
01333     // call this to ensure the GUI window is redrawn
01334     void NeedRedraw();
01335 
01336     void AddBlock( stg_point_t* pts, 
01337            size_t pt_count, 
01338            stg_meters_t zmin, 
01339            stg_meters_t zmax,
01340            stg_color_t color,
01341            bool inherit_color );
01342 
01343     void AddBlockRect( double x, double y, 
01344                double width, double height );
01345 
01347     void ClearBlocks();
01348 
01349     const char* TypeStr(){ return this->typestr; }
01350     StgModel* Parent(){ return this->parent; }
01351     StgModel* GetModel( const char* name );
01352     bool Stall(){ return this->stall; }
01353     int GuiMask(){ return this->gui_mask; };  
01354     StgWorld* GetWorld(){ return this->world; }
01355 
01357     StgModel* Root()
01358     { return(  parent ? parent->Root() : this ); }
01359   
01360     bool ObstacleReturn(){ return obstacle_return; }  
01361     stg_laser_return_t GetLaserReturn(){ return laser_return; }
01362     int GetRangerReturn(){ return ranger_return; }  
01363     int FiducialReturn(){ return fiducial_return; }
01364     int FiducialKey(){ return fiducial_key; }
01365 
01366     bool IsAntecedent( StgModel* testmod );
01367 
01368     // returns true if model [testmod] is a descendent of model [mod]
01369     bool IsDescendent( StgModel* testmod );
01370 
01371     bool IsRelated( StgModel* mod2 );
01372 
01374     stg_pose_t GetGlobalPose();
01375 
01377     stg_velocity_t GetGlobalVelocity();
01378 
01379     /* set the velocity of a model in the global coordinate system */
01380     void SetGlobalVelocity(  stg_velocity_t gvel );
01381 
01383     void Subscribe();
01384 
01386     void Unsubscribe();
01387 
01389     void SetGlobalPose(  stg_pose_t gpose );
01390   
01392     void SetVelocity(  stg_velocity_t vel );
01393  
01395     void SetPose(  stg_pose_t pose );
01396 
01398     void AddToPose(  stg_pose_t pose );
01399 
01401     void AddToPose(  double dx, double dy, double dz, double da );
01402 
01404     void SetGeom(  stg_geom_t src );
01405 
01407     void SetFiducialReturn(  int fid );
01408 
01411     void SetFiducialKey(  int key );
01412   
01413     stg_color_t GetColor(){ return color; }
01414   
01415     //  stg_laser_return_t GetLaserReturn(){ return laser_return; }
01416   
01418     int SetParent( StgModel* newparent);
01419   
01422     stg_geom_t GetGeom(){ return geom; }
01423 
01425     stg_pose_t GetPose(){ return pose; }
01426 
01428     stg_velocity_t GetVelocity(){ return velocity; }
01429 
01430     // guess what these do?
01431     void SetColor( stg_color_t col );
01432     void SetMass( stg_kg_t mass );
01433     void SetStall( stg_bool_t stall );
01434     void SetGripperReturn( int val );
01435     void SetLaserReturn( stg_laser_return_t val );
01436     void SetObstacleReturn( int val );
01437     void SetBlobReturn( int val );
01438     void SetRangerReturn( int val );
01439     void SetBoundary( int val );
01440     void SetGuiNose( int val );
01441     void SetGuiMask( int val );
01442     void SetGuiGrid( int val );
01443     void SetGuiOutline( int val );
01444     void SetWatts( stg_watts_t watts );
01445     void SetMapResolution( stg_meters_t res );
01446 
01447     bool DataIsFresh(){ return this->data_fresh; }
01448   
01449     /* attach callback functions to data members. The function gets
01450        called when the member is changed using SetX() accessor method */
01451 
01452     void AddCallback( void* address, 
01453               stg_model_callback_t cb, 
01454               void* user );
01455   
01456     int RemoveCallback( void* member,
01457             stg_model_callback_t callback );
01458   
01459     void CallCallbacks(  void* address );
01460   
01461     /* wrappers for the generic callback add & remove functions that hide
01462        some implementation detail */
01463   
01464     void AddStartupCallback( stg_model_callback_t cb, void* user )
01465     { AddCallback( &startup, cb, user ); };
01466   
01467     void RemoveStartupCallback( stg_model_callback_t cb )
01468     { RemoveCallback( &startup, cb ); };
01469   
01470     void AddShutdownCallback( stg_model_callback_t cb, void* user )
01471     { AddCallback( &shutdown, cb, user ); };
01472   
01473     void RemoveShutdownCallback( stg_model_callback_t cb )
01474     { RemoveCallback( &shutdown, cb ); }
01475   
01476     void AddLoadCallback( stg_model_callback_t cb, void* user )
01477     { AddCallback( &load, cb, user ); }
01478   
01479     void RemoveLoadCallback( stg_model_callback_t cb )
01480     { RemoveCallback( &load, cb ); }
01481   
01482     void AddSaveCallback( stg_model_callback_t cb, void* user )
01483     { AddCallback( &save, cb, user ); }
01484   
01485     void RemoveSaveCallback( stg_model_callback_t cb )
01486     { RemoveCallback( &save, cb ); }
01487   
01488     void AddUpdateCallback( stg_model_callback_t cb, void* user )
01489     { AddCallback( &update, cb, user ); }
01490   
01491     void RemoveUpdateCallback( stg_model_callback_t cb )
01492     { RemoveCallback( &update, cb ); }
01493   
01496     void* GetProperty( char* key );
01497 
01528     int SetProperty( char* key, void* data );    
01529     void UnsetProperty( char* key );
01530   
01531 
01532     void AddPropertyToggles( void* member, 
01533                  stg_model_callback_t callback_on,
01534                  void* arg_on,
01535                  stg_model_callback_t callback_off,
01536                  void* arg_off,
01537                  char* name,
01538                  char* label,
01539                  gboolean enabled );  
01540 
01541     virtual void Print( char* prefix );
01542     virtual const char* PrintWithPose();
01543 
01547     void GlobalToLocal( stg_pose_t* pose );
01548   
01552     //void LocalToGlobal( stg_pose_t* pose );
01553     
01556     stg_pose_t LocalToGlobal( stg_pose_t pose );
01557 
01560     stg_point3_t LocalToGlobal( stg_point3_t local );
01561   
01564     StgModel* GetUnsubscribedModelOfType( char* modelstr );
01565   
01566     // static wrapper for the constructor - all models must implement
01567     // this method and add an entry in typetable.cc
01568     static StgModel* Create( StgWorld* world,
01569                  StgModel* parent, 
01570                  stg_id_t id, 
01571                  char* typestr )
01572     { 
01573       return new StgModel( world, parent, id, typestr ); 
01574     }    
01575 
01576     // iff true, model may output some debugging visualizations and other info
01577     bool debug;
01578 
01579   };
01580   
01581   // BLOCKS
01582   class StgBlock
01583   {
01584   public:
01585   
01589     StgBlock( StgModel* mod,
01590           stg_point_t* pts, 
01591           size_t pt_count,
01592           stg_meters_t height,
01593           stg_meters_t z_offset,
01594           stg_color_t color,
01595           bool inherit_color );
01596   
01597     ~StgBlock();
01598   
01599     void Map();
01600     void UnMap(); // draw the block into the world
01601   
01602     void DrawGlobal(); // draw the block in OpenGL using pts_global coords
01603     void Draw(); // draw the block in OpenGL
01604     void Draw2D(); // draw the block in OpenGL
01605     void DrawSolid(); // draw the block in OpenGL as a solid single color
01606     void DrawFootPrint(); // draw the projection of the block onto the z=0 plane
01607     
01608     static void ScaleList( GList* blocks, stg_size_t* size );
01609     void RecordRenderPoint( GSList** head, GSList* link, unsigned int* c1, unsigned int* c2 );
01610   
01611     StgModel* Model(){ return mod; };
01612   
01613     stg_point_t* Points( unsigned int *count )
01614     { if( count ) *count = pt_count; return pts; };        
01615   
01616     bool IntersectGlobalZ( stg_meters_t z )
01617     { return( z >= global_zmin &&  z < global_zmax ); }
01618   
01619     stg_color_t Color()
01620     { return( inherit_color ? mod->GetColor() : color ); }
01621 
01622   private:
01623     stg_point_t* pts; //< points defining a polygon
01624     size_t pt_count; //< the number of points
01625     stg_meters_t zmin; 
01626     stg_meters_t zmax; 
01627 
01628     stg_meters_t global_zmin; 
01629     stg_meters_t global_zmax; 
01630 
01631     StgModel* mod; //< model to which this block belongs
01632 
01633     stg_point_int_t* pts_global_pixels; //< points defining a polygon in global coords
01634     stg_vertex_t* global_vertices; //< points defining a polygon in global coords
01635     //GLubyte* colors;
01636     GLubyte* edge_indices;
01637     
01638     stg_color_t color;
01639     bool inherit_color;  
01640 
01641     GArray* rendered_points;
01642 
01643     inline void DrawTop();
01644     inline void DrawSides();
01645   
01646     inline void PushColor( stg_color_t col )
01647     { mod->PushColor( col ); }
01648   
01649     inline void PushColor( double r, double g, double b, double a )
01650     { mod->PushColor( r,g,b,a ); }
01651 
01652     inline void PopColor()
01653     { mod->PopColor(); }
01654   };
01655 
01656   // COLOR STACK CLASS
01657   class GlColorStack
01658   {
01659   public:
01660     GlColorStack();
01661     ~GlColorStack();
01662   
01663     void Push( GLdouble col[4] );
01664     void Push( double r, double g, double b, double a );
01665     void Push( double r, double g, double b );
01666     void Push( stg_color_t col );
01667   
01668     void Pop();
01669   
01670     unsigned int Length()
01671     { return g_queue_get_length( colorstack ); }
01672 
01673   private:
01674     GQueue* colorstack;
01675   };
01676 
01677 
01680   class StgCanvas : public Fl_Gl_Window
01681   {
01682     friend class StgWorldGui; // allow access to private members
01683 
01684   private:
01685     GlColorStack colorstack;
01686     double scale;
01687     double panx, pany, stheta, sphi;
01688     int startx, starty;
01689     bool dragging;
01690     bool rotating;
01691     GList* selected_models; 
01692 
01693     StgModel* last_selection; 
01694 
01695     uint32_t showflags;
01696     stg_msec_t interval; // window refresh interval in ms
01697 
01698     GList* ray_list;
01699     void RecordRay( double x1, double y1, double x2, double y2 );
01700     void DrawRays();
01701     void ClearRays();
01702     void DrawGlobalGrid();
01703 
01704   public:
01705     StgCanvas( StgWorld* world, int x, int y, int W,int H);
01706     ~StgCanvas();
01707   
01708     bool graphics;
01709     StgWorld* world;
01710 
01711     void FixViewport(int W,int H);
01712     virtual void draw();
01713     virtual int handle( int event );
01714     void resize(int X,int Y,int W,int H);
01715 
01716     void CanvasToWorld( int px, int py, 
01717             double *wx, double *wy, double* wz );
01718 
01719     StgModel* Select( int x, int y );
01720   
01721     inline void PushColor( stg_color_t col )
01722     { colorstack.Push( col ); } 
01723   
01724     void PushColor( double r, double g, double b, double a )
01725     { colorstack.Push( r,g,b,a ); }
01726   
01727     void PopColor(){ colorstack.Pop(); } 
01728   
01729     void InvertView( uint32_t invertflags );
01730 
01731     uint32_t GetShowFlags(){ return showflags; }
01732 
01733     void SetShowFlags( uint32_t flags ){ showflags = flags; }
01734 
01735     static void TimerCallback( StgCanvas* canvas );
01736   };
01737 
01739   class StgWorldGui : public StgWorld, public Fl_Window 
01740   {
01741     friend class StgCanvas;
01742   
01743   private:
01744     int wf_section;
01745     StgCanvas* canvas;
01746     Fl_Menu_Bar* mbar;
01747     //StgBlockGrid* GetBlockGrid(){ return bgridx; };
01748 
01749   public:
01750     StgWorldGui(int W,int H,const char*L=0);
01751     ~StgWorldGui();
01752 
01753     // overload inherited methods
01754     virtual bool RealTimeUpdate();
01755     virtual bool Update();
01756 
01757     virtual void Load( const char* filename );
01758     virtual void Save();
01759   
01760     // static callback functions
01761     static void SaveCallback( Fl_Widget* wid, StgWorldGui* world );
01762   
01763     virtual void PushColor( stg_color_t col )
01764     { canvas->PushColor( col ); } 
01765   
01766     virtual void PushColor( double r, double g, double b, double a )
01767     { canvas->PushColor( r,g,b,a ); }
01768   
01769     virtual void PopColor()
01770     { canvas->PopColor(); } 
01771 
01772     void DrawTree( bool leaves );
01773     void DrawFloor();
01774   };
01775 
01776 
01777 
01778   // end doc group libstage_utilities
01779 
01780 
01781   // BLOBFINDER MODEL --------------------------------------------------------
01782   
01785   typedef struct
01786   {
01787     stg_color_t color;
01788     uint32_t left, top, right, bottom;
01789     stg_meters_t range;
01790   } stg_blobfinder_blob_t;
01791 
01792 
01793   class StgModelBlobfinder : public StgModel
01794   {
01795   private:
01796   
01797     GArray* colors;
01798     GArray* blobs;
01799   
01800     // predicate for ray tracing
01801     static bool BlockMatcher( StgBlock* testblock, StgModel* finder );
01802   
01803   public:
01804   
01805     unsigned int scan_width;
01806     unsigned int scan_height;
01807     stg_meters_t range;
01808     stg_radians_t fov;
01809     stg_radians_t pan;
01810 
01811     // constructor
01812     StgModelBlobfinder( StgWorld* world,
01813             StgModel* parent, 
01814             stg_id_t id, 
01815             char* typestr);
01816   
01817     // destructor
01818     ~StgModelBlobfinder();
01819     
01820     virtual void Startup();
01821     virtual void Shutdown();
01822     virtual void Update();
01823     virtual void Load();
01824     virtual void DataVisualize();
01825 
01826     stg_blobfinder_blob_t* GetBlobs( unsigned int* count )
01827     { 
01828       if( count ) *count = blobs->len;
01829       return (stg_blobfinder_blob_t*)blobs->data;
01830     }
01831 
01833     void AddColor( stg_color_t col );
01834 
01836     void RemoveColor( stg_color_t col );
01837   
01840     void RemoveAllColors();
01841 
01842     // static wrapper for the constructor - all models must implement
01843     // this method and add an entry in typetable.cc
01844     static StgModel* Create( StgWorld* world,
01845                  StgModel* parent, 
01846                  stg_id_t id, 
01847                  char* typestr )
01848     { 
01849       return (StgModel*)new StgModelBlobfinder( world, parent, id, typestr ); 
01850     }    
01851   };
01852   
01853   // ENERGY model --------------------------------------------------------------
01854   
01856   typedef struct
01857   {
01859     stg_joules_t stored;
01860 
01862     stg_bool_t charging;
01863 
01865     stg_meters_t range;
01866 
01868     GPtrArray* connections;
01869   } stg_energy_data_t;
01870 
01872   typedef struct
01873   {
01875     stg_joules_t capacity;
01876 
01878     stg_watts_t give_rate;
01879 
01881     stg_watts_t take_rate;
01882 
01884     stg_meters_t probe_range;
01885     
01887     stg_bool_t give;
01888 
01889   } stg_energy_config_t;
01890 
01891   // there is currently no energy command packet
01892 
01893   
01894   // LASER MODEL --------------------------------------------------------
01895   
01898   typedef struct
01899   {
01900     stg_meters_t range; 
01901     double reflectance; 
01902   } stg_laser_sample_t;
01903 
01904   typedef struct
01905   {
01906     uint32_t sample_count;
01907     uint32_t resolution;
01908     stg_range_bounds_t range_bounds;
01909     stg_radians_t fov;
01910   } stg_laser_cfg_t;
01911 
01912   class StgModelLaser : public StgModel
01913   {
01914   private:
01915     int dl_debug_laser;
01916   
01917     stg_laser_sample_t* samples;
01918     uint32_t sample_count;
01919     stg_meters_t range_min, range_max;
01920     stg_radians_t fov;
01921     uint32_t resolution;
01922   
01923   public:
01924     // constructor
01925     StgModelLaser( StgWorld* world,
01926            StgModel* parent, 
01927            stg_id_t id, 
01928            char* typestr );
01929   
01930     // destructor
01931     ~StgModelLaser();
01932   
01933     virtual void Startup();
01934     virtual void Shutdown();
01935     virtual void Update();
01936     virtual void Load();  
01937     virtual void Print( char* prefix );
01938     virtual void DataVisualize();
01939   
01940     uint32_t GetSampleCount(){ return sample_count; }
01941     
01942     stg_laser_sample_t* GetSamples( uint32_t* count=NULL);
01943     
01944     void SetSamples( stg_laser_sample_t* samples, uint32_t count);
01945     
01946     // Get the user-tweakable configuration of the laser
01947     stg_laser_cfg_t GetConfig( );    
01948 
01949     // Set the user-tweakable configuration of the laser
01950     void SetConfig( stg_laser_cfg_t cfg );
01951   
01952   
01953     // static wrapper for the constructor - all models must implement
01954     // this method and add an entry in typetable.cc
01955     static StgModel* Create( StgWorld* world,
01956                  StgModel* parent, 
01957                  stg_id_t id, 
01958                  char* typestr )
01959     { 
01960       return (StgModel*)new StgModelLaser( world, parent, id, typestr ); 
01961     }    
01962   };
01963 
01964   // \todo  GRIPPER MODEL --------------------------------------------------------
01965   
01966 //   typedef enum {
01967 //     STG_GRIPPER_PADDLE_OPEN = 0, // default state
01968 //     STG_GRIPPER_PADDLE_CLOSED, 
01969 //     STG_GRIPPER_PADDLE_OPENING,
01970 //     STG_GRIPPER_PADDLE_CLOSING,
01971 //   } stg_gripper_paddle_state_t;
01972 
01973 //   typedef enum {
01974 //     STG_GRIPPER_LIFT_DOWN = 0, // default state
01975 //     STG_GRIPPER_LIFT_UP, 
01976 //     STG_GRIPPER_LIFT_UPPING, // verbed these to match the paddle state
01977 //     STG_GRIPPER_LIFT_DOWNING, 
01978 //   } stg_gripper_lift_state_t;
01979   
01980 //   typedef enum {
01981 //     STG_GRIPPER_CMD_NOP = 0, // default state
01982 //     STG_GRIPPER_CMD_OPEN, 
01983 //     STG_GRIPPER_CMD_CLOSE,
01984 //     STG_GRIPPER_CMD_UP, 
01985 //     STG_GRIPPER_CMD_DOWN    
01986 //   } stg_gripper_cmd_type_t;
01987   
01988 //   /** gripper configuration packet
01989 //    */
01990 //   typedef struct
01991 //   {
01992 //     stg_size_t paddle_size; ///< paddle dimensions 
01993 
01994 //     stg_gripper_paddle_state_t paddles; 
01995 //     stg_gripper_lift_state_t lift;
01996 
01997 //     double paddle_position; ///< 0.0 = full open, 1.0 full closed
01998 //     double lift_position; ///< 0.0 = full down, 1.0 full up
01999 
02000 //     stg_meters_t inner_break_beam_inset; ///< distance from the end of the paddle
02001 //     stg_meters_t outer_break_beam_inset; ///< distance from the end of the paddle  
02002 //     stg_bool_t paddles_stalled; // true iff some solid object stopped
02003 //              // the paddles closing or opening
02004     
02005 //     GSList *grip_stack;  ///< stack of items gripped
02006 //     int grip_stack_size; ///< maximum number of objects in stack, or -1 for unlimited
02007 
02008 //     double close_limit; ///< How far the gripper can close. If < 1.0, the gripper has its mouth full.
02009 
02010 //   } stg_gripper_config_t;
02011 
02012 //   /** gripper command packet
02013 //    */
02014 //   typedef struct
02015 //   {
02016 //     stg_gripper_cmd_type_t cmd;
02017 //     int arg;
02018 //   } stg_gripper_cmd_t;
02019 
02020 
02021 //   /** gripper data packet
02022 //    */
02023 //   typedef struct
02024 //   {
02025 //     stg_gripper_paddle_state_t paddles; 
02026 //     stg_gripper_lift_state_t lift;
02027     
02028 //     double paddle_position; ///< 0.0 = full open, 1.0 full closed
02029 //     double lift_position; ///< 0.0 = full down, 1.0 full up
02030 
02031 //     stg_bool_t inner_break_beam; ///< non-zero iff beam is broken
02032 //     stg_bool_t outer_break_beam; ///< non-zero iff beam is broken
02033     
02034 //     stg_bool_t paddle_contacts[2]; ///< non-zero iff paddles touch something
02035 
02036 //     stg_bool_t paddles_stalled; // true iff some solid object stopped
02037 //              // the paddles closing or opening
02038 
02039 //     int stack_count; ///< number of objects in stack
02040 
02041 
02042 //   } stg_gripper_data_t;
02043 
02044 
02045   // \todo BUMPER MODEL --------------------------------------------------------
02046 
02047 //   typedef struct
02048 //   {
02049 //     stg_pose_t pose;
02050 //     stg_meters_t length;
02051 //   } stg_bumper_config_t;
02052   
02053 //   typedef struct
02054 //   {
02055 //     StgModel* hit;
02056 //     stg_point_t hit_point;
02057 //   } stg_bumper_sample_t;
02058 
02059 
02060   // FIDUCIAL MODEL --------------------------------------------------------
02061   
02064   typedef struct
02065   {
02066     stg_meters_t max_range_anon; //< maximum detection range
02067     stg_meters_t max_range_id; 
02068     stg_meters_t min_range; 
02069     stg_radians_t fov; 
02070     stg_radians_t heading; 
02071     
02074     int key;
02075   } stg_fiducial_config_t;
02076   
02079   typedef struct
02080   {
02081     stg_meters_t range; 
02082     stg_radians_t bearing; 
02083     stg_pose_t geom; 
02084     stg_pose_t pose; 
02085     int id; 
02086     
02087   } stg_fiducial_t;
02088 
02089   class StgModelFiducial : public StgModel
02090   {
02091   private:
02092     // if neighbor is visible, add him to the fiducial scan
02093     void AddModelIfVisible( StgModel* him );
02094   
02095     // static wrapper function can be used as a function pointer
02096     static void AddModelIfVisibleStatic( gpointer key, 
02097                      StgModel* him, 
02098                      StgModelFiducial* me )
02099     { if( him != me ) me->AddModelIfVisible( him ); };
02100 
02101     virtual void Update();
02102     virtual void DataVisualize();
02103   
02104     GArray* data;
02105 
02106   public:
02107     // constructor
02108     StgModelFiducial( StgWorld* world,
02109               StgModel* parent, 
02110               stg_id_t id, 
02111               char* typestr );
02112   
02113     // destructor
02114     virtual ~StgModelFiducial();
02115   
02116     virtual void Load();
02117   
02118     stg_meters_t max_range_anon; //< maximum detection range
02119     stg_meters_t max_range_id; 
02120     stg_meters_t min_range; 
02121     stg_radians_t fov; 
02122     stg_radians_t heading; 
02123     int key; 
02124   
02125     stg_fiducial_t* fiducials; 
02126     uint32_t fiducial_count; 
02127   
02128     // static wrapper for the constructor - all models must implement
02129     // this method and add an entry in typetable.cc
02130     static StgModel* Create( StgWorld* world,
02131                  StgModel* parent, 
02132                  stg_id_t id, 
02133                  char* typestr )
02134     { 
02135       return (StgModel*)new StgModelFiducial( world, parent, id, typestr ); 
02136     }    
02137   };
02138 
02139 
02140   // RANGER MODEL --------------------------------------------------------
02141 
02142   typedef struct
02143   {
02144     stg_pose_t pose;
02145     stg_size_t size;
02146     stg_bounds_t bounds_range;
02147     stg_radians_t fov;
02148     int ray_count;
02149   } stg_ranger_sensor_t;
02150 
02151   class StgModelRanger : public StgModel
02152   {
02153   protected:
02154   
02155     virtual void Startup();
02156     virtual void Shutdown();
02157     virtual void Update();
02158     virtual void DataVisualize();
02159   
02160   public:
02161     // constructor
02162     StgModelRanger( StgWorld* world,
02163             StgModel* parent, 
02164             stg_id_t id, 
02165             char* typestr );
02166   
02167     // destructor
02168     virtual ~StgModelRanger();
02169   
02170     virtual void Load();
02171     virtual void Print( char* prefix );
02172   
02173     uint32_t sensor_count;
02174     stg_ranger_sensor_t* sensors;
02175     stg_meters_t* samples;
02176   
02177     // static wrapper for the constructor - all models must implement
02178     // this method and add an entry in typetable.cc
02179     static StgModel* Create( StgWorld* world,
02180                  StgModel* parent, 
02181                  stg_id_t id, 
02182                  char* typestr )
02183     { 
02184       return (StgModel*)new StgModelRanger( world, parent, id, typestr ); 
02185     }    
02186   };
02187 
02188   // BLINKENLIGHT MODEL ----------------------------------------------------
02189   class StgModelBlinkenlight : public StgModel
02190   {
02191   private:
02192     double dutycycle;
02193     bool enabled;
02194     double period;
02195     bool on;
02196 
02197   public:
02198 
02199     StgModelBlinkenlight( StgWorld* world,
02200               StgModel* parent, 
02201               stg_id_t id, 
02202               char* typestr );
02203 
02204     ~StgModelBlinkenlight();
02205 
02206     virtual void Load();
02207     virtual void Update();
02208     virtual void Draw( uint32_t flags );
02209 
02210     // static wrapper for the constructor - all models must implement
02211     // this method and add an entry in typetable.cc
02212     static StgModel* Create( StgWorld* world,
02213                  StgModel* parent, 
02214                  stg_id_t id, 
02215                  char* typestr )
02216     { 
02217       return (StgModel*)new StgModelBlinkenlight( world, parent, id, typestr ); 
02218     }    
02219   };
02220   
02221   // POSITION MODEL --------------------------------------------------------
02222   
02224   typedef enum
02225     { STG_POSITION_CONTROL_VELOCITY, 
02226       STG_POSITION_CONTROL_POSITION 
02227     } stg_position_control_mode_t;
02228   
02230   typedef enum
02231     { STG_POSITION_LOCALIZATION_GPS, 
02232       STG_POSITION_LOCALIZATION_ODOM 
02233     } stg_position_localization_mode_t;
02234   
02236   typedef enum
02237     { STG_POSITION_DRIVE_DIFFERENTIAL, 
02238       STG_POSITION_DRIVE_OMNI, 
02239       STG_POSITION_DRIVE_CAR 
02240     } stg_position_drive_mode_t;
02241   
02242   
02243   class StgModelPosition : public StgModel
02244   {
02245   private:
02246     stg_pose_t goal; //< the current velocity or pose to reach, depending on the value of control_mode
02247     stg_position_control_mode_t control_mode; 
02248     stg_position_drive_mode_t drive_mode;
02249     stg_position_localization_mode_t localization_mode; 
02250     stg_velocity_t integration_error; 
02251     stg_velocity_t integration_bias; 
02252     
02253   public:
02254     // constructor
02255     StgModelPosition( StgWorld* world,
02256               StgModel* parent, 
02257               stg_id_t id, 
02258               char* typestr);
02259   
02260     // destructor
02261     ~StgModelPosition();
02262     
02263     virtual void Startup();
02264     virtual void Shutdown();
02265     virtual void Update();
02266     virtual void Load();
02267 
02269     void SetOdom( stg_pose_t odom );
02270   
02273     void SetSpeed( double x, double y, double a ); 
02274     void SetXSpeed( double x ); 
02275     void SetYSpeed( double y ); 
02276     void SetZSpeed( double z ); 
02277     void SetTurnSpeed( double a ); 
02278     void SetSpeed( stg_velocity_t vel );
02279 
02282     void GoTo( double x, double y, double a );
02283     void GoTo( stg_pose_t pose );
02284   
02285     // localization state
02286     stg_pose_t est_pose; 
02287     stg_pose_t est_pose_error; 
02288     stg_pose_t est_origin; 
02289 
02290     // static wrapper for the constructor - all models must implement
02291     // this method and add an entry in typetable.cc
02292     static StgModel* Create( StgWorld* world,
02293                  StgModel* parent, 
02294                  stg_id_t id, 
02295                  char* typestr )
02296     { 
02297       return (StgModel*)new StgModelPosition( world, parent, id, typestr ); 
02298     }    
02299 
02300   };
02301 
02302 
02303 }; // end namespace stg
02304 
02307 #endif

Generated on Thu Jan 7 17:42:16 2010 for Stage by  doxygen 1.5.5