avonstage.cc
Go to the documentation of this file.
00001 
00007 #include <getopt.h>
00008 
00009 extern "C" {
00010 #include <avon.h>
00011 }
00012 
00013 #include "stage.hh"
00014 #include "config.h"
00015 
00016 const char* AVONSTAGE_VERSION = "1.0.0";
00017 
00018 const char* USAGE = 
00019   "USAGE:  stage [options] <worldfile1> [worldfile2 ... worldfileN]\n"
00020   "Available [options] are:\n"
00021   "  --clock        : print simulation time peridically on standard output\n"
00022   "  -c             : equivalent to --clock\n"
00023   "  --gui          : run without a GUI\n"
00024   "  -g             : equivalent to --gui\n"
00025   "  --help         : print this message\n"
00026   "  --args \"str\" : define an argument string to be passed to all controllers\n"
00027   "  -a \"str\"     : equivalent to --args \"str\"\n"
00028   "  --host \"str\" : set the http server host name (default: \"localhost\")\n"
00029   " --port num      : set the http sever port number (default: 8000)\n" 
00030   " --verbose       : provide lots of informative output\n"
00031   " -v              : equivalent to --verbose\n"
00032   "  -?             : equivalent to --help\n";
00033 
00034 /* options descriptor */
00035 static struct option longopts[] = {
00036         { "gui",  optional_argument,   NULL,  'g' },
00037         { "clock",  optional_argument,   NULL,  'c' },
00038         { "help",  optional_argument,   NULL,  'h' },
00039         { "args",  required_argument,   NULL,  'a' },
00040         { "verbose", no_argument, NULL, 'v' },
00041         { "port",  required_argument,   NULL,  'p' },
00042         { "host",  required_argument,   NULL,  'h' },
00043         { "rootdir",  required_argument,   NULL,  'r' },
00044         { NULL, 0, NULL, 0 }
00045 };
00046 
00047 
00048 
00049 uint64_t GetTimeWorld( Stg::World* world )
00050 {
00051   Stg::usec_t stgtime = world->SimTimeNow();  
00052   return static_cast<uint64_t>(stgtime);
00053 }
00054 
00055 uint64_t GetTime( Stg::Model* mod )
00056 {
00057   assert(mod);  
00058   return GetTimeWorld( mod->GetWorld() );
00059 }
00060 
00061 int GetModelPVA( Stg::Model* mod, av_pva_t* pva  )
00062 {
00063   assert(mod);
00064   assert(pva);
00065 
00066   bzero(pva,sizeof(av_pva_t));
00067   
00068   pva->time = GetTime(mod);  
00069   
00070   Stg::Pose sp = mod->GetPose(); 
00071 
00072   pva->p[0] = sp.x;
00073   pva->p[1] = sp.y;
00074   pva->p[2] = sp.z;
00075   pva->p[3] = 0;
00076   pva->p[4] = 0;
00077   pva->p[5] = sp.a;
00078   
00079   Stg::Velocity sv = mod->GetVelocity();                
00080   
00081   pva->v[0] = sv.x;
00082   pva->v[1] = sv.y;
00083   pva->v[2] = sv.z;
00084   pva->v[3] = 0;
00085   pva->v[4] = 0;
00086   pva->v[5] = sv.a;
00087   
00088   return 0; // ok
00089 }
00090 
00091 
00092 int SetModelPVA(  Stg::Model* mod, av_pva_t* p  )
00093 {
00094   assert(mod);
00095   assert(p);
00096   
00097   mod->SetPose( Stg::Pose( p->p[0], // x
00098                                                                         p->p[1], // y
00099                                                                         p->p[2], // z
00100                                                                         p->p[5] )); // a
00101   
00102   mod->SetVelocity( Stg::Velocity( p->v[0], // x
00103                                                                                           p->v[1], // y
00104                                                                                           p->v[2], // z
00105                                                                                           p->v[5] )); // a  
00106   return 0; // ok
00107 }
00108 
00109 
00110 int SetModelGeom(  Stg::Model* mod, av_geom_t* g )
00111 {       
00112   assert(mod);
00113   assert(g);
00114   
00115   mod->SetGeom( Stg::Geom( Stg::Pose(g->pose[0], 
00116                                                                                                                                                  g->pose[1], 
00117                                                                                                                                                  g->pose[2],
00118                                                                                                                                                  g->pose[5] ),
00119                                                                                                          Stg::Size(g->extent[0], 
00120                                                                                                                                                  g->extent[1], 
00121                                                                                                                                                  g->extent[2] )));
00122         
00123   // force GUI update to see the change if Stage was paused
00124   mod->Redraw();
00125   
00126   return 0; // ok
00127 }
00128 
00129 int GetModelGeom(  Stg::Model* mod, av_geom_t* g )
00130 {       
00131   assert(mod);
00132   assert(g);
00133   
00134   bzero(g, sizeof(av_geom_t));
00135 
00136   g->time = GetTime(mod);  
00137   
00138   Stg::Geom ext(mod->GetGeom());        
00139   g->pose[0] = ext.pose.x;
00140   g->pose[1] = ext.pose.y;
00141   g->pose[2] = ext.pose.a;
00142   g->extent[0] = ext.size.x;
00143   g->extent[1] = ext.size.y;
00144   g->extent[2] = ext.size.z;
00145 
00146   return 0; // ok
00147 }
00148 
00149 
00150 int RangerData( Stg::Model* mod, av_msg_t* data )
00151 {
00152   assert(mod);
00153   assert(data);
00154   
00155         if( ! mod->HasSubscribers() )
00156                 mod->Subscribe();
00157 
00158   /* Will set the data pointer in arg data to point to this static
00159           struct, thus avoiding dynamic memory allocation. This is deeply
00160           non-reentrant! but fast and simple code. */
00161   static av_ranger_data_t rd;
00162   bzero(&rd, sizeof(rd));  
00163   bzero(data, sizeof(av_msg_t));
00164   
00165   data->time = GetTime(mod);  
00166   data->interface = AV_INTERFACE_RANGER;
00167   data->data = (const void*)&rd;  
00168   
00169   Stg::ModelRanger* r = dynamic_cast<Stg::ModelRanger*>(mod);
00170   
00171   const std::vector<Stg::ModelRanger::Sensor>& sensors = r->GetSensors();
00172   
00173   rd.transducer_count = sensors.size();
00174   
00175   assert( rd.transducer_count <= AV_RANGER_TRANSDUCERS_MAX );
00176   
00177   rd.time = data->time;
00178 
00179           
00180   return 0; //ok
00181 }
00182 
00183 
00184 int RangerSet( Stg::Model* mod, av_msg_t* data )
00185 {
00186   assert(mod);
00187   assert(data);  
00188   puts( "ranger set does nothing" );  
00189   return 0; //ok
00190 }
00191 
00192 int RangerGet( Stg::Model* mod, av_msg_t* data )
00193 {
00194   assert(mod);
00195   assert(data);  
00196 
00197   static av_ranger_t rgr;
00198   bzero(&rgr,sizeof(rgr));
00199 
00200   data->time = GetTime(mod);  
00201   data->interface = AV_INTERFACE_RANGER;
00202   data->data = (const void*)&rgr;  
00203  
00204   rgr.time = data->time;
00205   
00206   Stg::ModelRanger* r = dynamic_cast<Stg::ModelRanger*>(mod);
00207   
00208   const std::vector<Stg::ModelRanger::Sensor>& sensors = r->GetSensors();
00209   
00210   rgr.transducer_count = sensors.size();
00211   
00212   assert( rgr.transducer_count <= AV_RANGER_TRANSDUCERS_MAX );
00213   
00214 
00215   for( unsigned int c=0; c<rgr.transducer_count; c++ )
00216          {              
00217                 // bearing
00218                 rgr.transducers[c].fov[0].min = -sensors[c].fov/2.0;
00219                 rgr.transducers[c].fov[0].max =  sensors[c].fov/2.0;
00220                 
00221                 //azimuth
00222                 rgr.transducers[c].fov[1].min = 0.0;
00223                 rgr.transducers[c].fov[1].max = 0.0;
00224                 
00225                 // range
00226                 rgr.transducers[c].fov[2].min = sensors[c].range.min;
00227                 rgr.transducers[c].fov[2].min = sensors[c].range.max;
00228                 
00229                 // pose 6dof
00230                 rgr.transducers[c].geom.pose[0] = sensors[c].pose.x;
00231                 rgr.transducers[c].geom.pose[1] = sensors[c].pose.y;
00232                 rgr.transducers[c].geom.pose[2] = sensors[c].pose.z;
00233                 rgr.transducers[c].geom.pose[3] = 0.0;
00234                 rgr.transducers[c].geom.pose[4] = 0.0;
00235                 rgr.transducers[c].geom.pose[5] = sensors[c].pose.a;
00236 
00237                 // extent 3dof
00238                 rgr.transducers[c].geom.extent[0] = sensors[c].size.x;
00239                 rgr.transducers[c].geom.extent[1] = sensors[c].size.y;
00240                 rgr.transducers[c].geom.extent[2] = sensors[c].size.z;
00241 
00242                 
00243                 av_ranger_transducer_data_t& t =        rgr.transducers[c];
00244                 const Stg::ModelRanger::Sensor& s = sensors[c];
00245                 
00246                 t.pose[0] = s.pose.x;
00247                 t.pose[1] = s.pose.y;
00248                 t.pose[2] = s.pose.z;
00249                 t.pose[3] = 0.0;
00250                 t.pose[4] = 0.0;
00251                 t.pose[5] = s.pose.a;           
00252                 
00253                 const std::vector<Stg::meters_t>& ranges = s.ranges;
00254                 const std::vector<double>& intensities = s.intensities;
00255                 
00256                 assert( ranges.size() == intensities.size() );
00257                 
00258                 t.sample_count = ranges.size(); 
00259                 
00260                 const double fov_max = s.fov / 2.0;
00261                 const double fov_min = -fov_max;
00262                 const double delta = (fov_max - fov_min) / (double)t.sample_count;
00263                 
00264                 for( unsigned int r=0; r<t.sample_count; r++ )
00265                   {
00266                          t.samples[r][AV_SAMPLE_BEARING] = fov_min + r*delta;
00267                          t.samples[r][AV_SAMPLE_AZIMUTH] = 0.0; // linear scanner
00268                          t.samples[r][AV_SAMPLE_RANGE] = ranges[r];
00269                          t.samples[r][AV_SAMPLE_INTENSITY] = intensities[r];
00270                   }
00271          }
00272   return 0; //ok
00273 }
00274 
00275 
00276 int FiducialData( Stg::Model* mod, av_msg_t* data )
00277 {
00278   assert(mod);
00279   assert(data);
00280   
00281         if( ! mod->HasSubscribers() )
00282                 mod->Subscribe();
00283 
00284   /* Will set the data pointer in arg data to point to this static
00285           struct, thus avoiding dynamic memory allocation. This is deeply
00286           non-reentrant! but fast and simple code. */
00287   static av_fiducial_data_t fd;
00288   bzero(&fd, sizeof(fd));  
00289   bzero(data, sizeof(av_msg_t));
00290   
00291   data->time = GetTime(mod);  
00292   data->interface = AV_INTERFACE_FIDUCIAL;
00293   data->data = (const void*)&fd;  
00294   
00295   Stg::ModelFiducial* fm = dynamic_cast<Stg::ModelFiducial*>(mod);
00296 
00297         const std::vector<Stg::ModelFiducial::Fiducial>& sf = fm->GetFiducials();
00298 
00299         fd.fiducial_count = sf.size();
00300         
00301         printf( "FIDUCIALS %u\n", fd.fiducial_count );
00302 
00303         for( size_t i=0; i<fd.fiducial_count; i++ )
00304                 {
00305                         fd.fiducials[i].pose[0] = sf[i].bearing;
00306                         fd.fiducials[i].pose[1] = 0.0; // no azimuth in Stage
00307                         fd.fiducials[i].pose[2] = sf[i].range;
00308                         
00309                         fd.fiducials[i].geom.pose[0] = 0.0; // sf[i].pose_rel.x;
00310                         fd.fiducials[i].geom.pose[1] = 0.0; // sf[i].pose_rel.y;
00311                         fd.fiducials[i].geom.pose[2] = 0.0;
00312                         fd.fiducials[i].geom.pose[3] = 0.0; 
00313                         fd.fiducials[i].geom.pose[4] = 0.0; 
00314                         fd.fiducials[i].geom.pose[5] = sf[i].geom.a;
00315                         
00316                         fd.fiducials[i].geom.extent[0] = sf[i].geom.x;
00317                         fd.fiducials[i].geom.extent[1] = sf[i].geom.y;
00318                         fd.fiducials[i].geom.extent[2] = sf[i].geom.z;
00319                 }
00320 
00321         return 0;
00322 }
00323 
00324 
00325 int FiducialSet( Stg::Model* mod, av_msg_t* data )
00326 {
00327   assert(mod);
00328   assert(data);  
00329   puts( "fiducial setcfg does nothing" );  
00330   return 0; //ok
00331 }
00332 
00333 
00334 int FiducialGet( Stg::Model* mod, av_msg_t* msg )
00335 {
00336         assert(mod);
00337         assert(msg);
00338         
00339         static av_fiducial_cfg_t cfg;
00340         bzero(&cfg,sizeof(cfg));
00341         
00342   msg->time = GetTime(mod);  
00343   msg->interface = AV_INTERFACE_FIDUCIAL;
00344   msg->data = (const void*)&cfg;  
00345 
00346         //      cfg.time = msg->time;
00347         
00348         Stg::ModelFiducial* fid = dynamic_cast<Stg::ModelFiducial*>(mod);
00349   
00350         // bearing
00351         cfg.fov[0].min = -fid->fov/2.0;
00352         cfg.fov[0].max = fid->fov/2.0;
00353 
00354         // azimuth
00355         cfg.fov[1].min = 0;
00356         cfg.fov[1].max = 0;
00357         
00358         // range
00359         cfg.fov[2].min = fid->min_range;
00360         cfg.fov[2].max = fid->max_range_anon;
00361 
00362         return 0; // ok
00363 }
00364 
00365 
00366 class Reg
00367 {
00368 public:
00369         std::string prototype;
00370         av_interface_t interface;
00371         av_prop_get_t getter;
00372         av_prop_set_t setter;
00373         
00374         Reg( const std::string& prototype, 
00375                          av_interface_t interface,
00376                          av_prop_get_t getter,
00377                          av_prop_set_t setter ) :
00378                 prototype(prototype), 
00379                 interface(interface),
00380                 getter(getter),
00381                 setter(setter)
00382         {}
00383 };
00384 
00385 std::pair<std::string,av_interface_t> proto_iface_pair_t;
00386 
00387 int RegisterModel( Stg::Model* mod, void* dummy )
00388 {       
00389         // expensive to test this here! XX todo optmize this for large pops
00390         if( mod->TokenStr() == "_ground_model" )
00391                 return 0;
00392         
00393         static std::map<std::string,Reg> type_table;
00394         
00395         if( type_table.size() == 0 ) // first call only
00396                 {
00397                         type_table[ "model" ] = 
00398                                 Reg( "generic", AV_INTERFACE_GENERIC,NULL,NULL );
00399                         
00400                         type_table[ "position" ] = 
00401                                 Reg( "position2d", AV_INTERFACE_GENERIC,NULL,NULL );
00402                         
00403                         type_table[ "ranger" ] = 
00404                                 Reg( "ranger", AV_INTERFACE_RANGER, RangerGet, RangerSet );
00405                         
00406                         type_table[ "fiducial" ] = 
00407                                 Reg( "fiducial", AV_INTERFACE_FIDUCIA, FiducualGet, FiducualSet );
00408                 }
00409         
00410   printf( "[AvonStage] registering %s\n", mod->Token() );
00411                 
00412         // look up the model type in the table
00413 
00414         const std::map<std::string,proto_iface_pair_t>::iterator it = 
00415                 type_table.find( mod->GetModelType() );
00416 
00417         if( it != type_table.end() ) // if we found it in the table
00418                 {                       
00419                         Stg::Model* parent = mod->Parent();
00420                         const char* parent_name = parent ? parent->Token() : NULL;
00421                         
00422                         av_register_object( mod->Token(),
00423                                                                                                         parent_name,  
00424                                                                                                         it->prototype.c_str(), 
00425                                                                                                         it->interface, 
00426                                                                                                         it->getter,
00427                                                                                                         it->setter,
00428                                                                                                         dynamic_cast<void*>(mod) );
00429                         return 0; // ok
00430                 }
00431         
00432         // else
00433         printf( "Avonstage error: model type \"%s\" not found.\n", 
00434                                         mod->GetModelType().c_str() );
00435         return 1; //fail
00436 }
00437 
00438 int main( int argc, char* argv[] )
00439 {
00440   // initialize libstage - call this first
00441   Stg::Init( &argc, &argv );
00442 
00443   printf( "%s %s ", PROJECT, VERSION );
00444   
00445   int ch=0, optindex=0;
00446   bool usegui = true;
00447   bool showclock = false;
00448   
00449   std::string host = "localhost";
00450   std::string rootdir = ".";
00451   unsigned short port = AV_DEFAULT_PORT;
00452   bool verbose = false;
00453 
00454   while ((ch = getopt_long(argc, argv, "cvrgh?p?", longopts, &optindex)) != -1)
00455          {
00456                 switch( ch )
00457                   {
00458                   case 0: // long option given
00459                          printf( "option %s given\n", longopts[optindex].name );
00460                          break;
00461 
00462                          // stage options
00463                   case 'a':
00464                          Stg::World::ctrlargs = std::string(optarg);
00465                          break;
00466                   case 'c': 
00467                          showclock = true;
00468                          printf( "[Clock enabled]" );
00469                          break;
00470                   case 'g': 
00471                          usegui = false;
00472                          printf( "[GUI disabled]" );
00473                          break;
00474                          
00475                          // avon options
00476                   case 'p':
00477                          port = atoi(optarg);
00478                          break;
00479                   case 'h':
00480                          host = std::string(optarg);
00481                          break;
00482                          //               case 'f':
00483                          //                      fedfilename = optarg;
00484                          //                      usefedfile = true;
00485                          //                      break;
00486                   case 'r':
00487                          rootdir = std::string(optarg);
00488                          break;
00489                   case 'v':
00490                          verbose = true;
00491                          break;
00492                          // help options
00493                   case '?':  
00494                          puts( USAGE );
00495                          exit(0);
00496                          break;
00497                   default:
00498                          printf("unhandled option %c\n", ch );
00499                          puts( USAGE );
00500                          //exit(0);
00501                   }
00502          }
00503   
00504   const char* worldfilename = argv[optind];
00505 
00506   if( worldfilename == NULL )
00507          {      
00508                 puts( "[AvonStage] no worldfile specified on command line. Quit.\n" );
00509                 exit(-1);
00510          }
00511 
00512   puts("");// end the first start-up line
00513   
00514   printf( "[AvonStage] host %s:%u world %s\n",
00515                          host.c_str(), 
00516                          port, 
00517                          worldfilename );
00518   
00519         char version[1024];
00520         snprintf( version, 1024, "%s (%s-%s)",
00521                                                 AVONSTAGE_VERSION,
00522                                                 PROJECT,
00523                                                 VERSION );
00524 
00525   // avon
00526   av_init( host.c_str(), port, rootdir.c_str(), verbose, "AvonStage", version );
00527 
00528   
00529   // arguments at index [optindex] and later are not options, so they
00530   // must be world file names
00531   
00532   
00533   Stg::World* world = ( usegui ? 
00534                                                                                                 new Stg::WorldGui( 400, 300, worldfilename ) : 
00535                                                                                                 new Stg::World( worldfilename ) );
00536         
00537   world->Load( worldfilename );
00538   world->ShowClock( showclock );
00539         
00540         // now we have a world object, we can install a clock callback
00541         av_install_clock_callbacks( (av_clock_get_t)GetTimeWorld, world );
00542         
00543   // start the http server
00544   av_startup();
00545         
00546   // register all models here  
00547   world->ForEachDescendant( RegisterModel, NULL );
00548  
00549   if( ! world->paused ) 
00550          world->Start();
00551     
00552   while( 1 )
00553          {
00554                 // TODO - loop properly
00555 
00556                 Fl::check(); 
00557                 av_check();      
00558 
00559                 usleep(100); // TODO - loop sensibly here
00560          }
00561   
00562   puts( "\n[AvonStage: done]" );
00563   
00564   return EXIT_SUCCESS;
00565 }


stage
Author(s): Richard Vaughan , Brian Gerkey , Reed Hedges , Andrew Howard , Toby Collett , Pooya Karimian , Jeremy Asher , Alex Couture-Beil , Geoff Biggs , Rich Mattes , Abbas Sadat
autogenerated on Thu Aug 27 2015 15:20:57