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
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;
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],
00098 p->p[1],
00099 p->p[2],
00100 p->p[5] ));
00101
00102 mod->SetVelocity( Stg::Velocity( p->v[0],
00103 p->v[1],
00104 p->v[2],
00105 p->v[5] ));
00106 return 0;
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
00124 mod->Redraw();
00125
00126 return 0;
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;
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
00159
00160
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;
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;
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
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
00222 rgr.transducers[c].fov[1].min = 0.0;
00223 rgr.transducers[c].fov[1].max = 0.0;
00224
00225
00226 rgr.transducers[c].fov[2].min = sensors[c].range.min;
00227 rgr.transducers[c].fov[2].min = sensors[c].range.max;
00228
00229
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
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;
00268 t.samples[r][AV_SAMPLE_RANGE] = ranges[r];
00269 t.samples[r][AV_SAMPLE_INTENSITY] = intensities[r];
00270 }
00271 }
00272 return 0;
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
00285
00286
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;
00307 fd.fiducials[i].pose[2] = sf[i].range;
00308
00309 fd.fiducials[i].geom.pose[0] = 0.0;
00310 fd.fiducials[i].geom.pose[1] = 0.0;
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;
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
00347
00348 Stg::ModelFiducial* fid = dynamic_cast<Stg::ModelFiducial*>(mod);
00349
00350
00351 cfg.fov[0].min = -fid->fov/2.0;
00352 cfg.fov[0].max = fid->fov/2.0;
00353
00354
00355 cfg.fov[1].min = 0;
00356 cfg.fov[1].max = 0;
00357
00358
00359 cfg.fov[2].min = fid->min_range;
00360 cfg.fov[2].max = fid->max_range_anon;
00361
00362 return 0;
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
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 )
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
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() )
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;
00430 }
00431
00432
00433 printf( "Avonstage error: model type \"%s\" not found.\n",
00434 mod->GetModelType().c_str() );
00435 return 1;
00436 }
00437
00438 int main( int argc, char* argv[] )
00439 {
00440
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:
00459 printf( "option %s given\n", longopts[optindex].name );
00460 break;
00461
00462
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
00476 case 'p':
00477 port = atoi(optarg);
00478 break;
00479 case 'h':
00480 host = std::string(optarg);
00481 break;
00482
00483
00484
00485
00486 case 'r':
00487 rootdir = std::string(optarg);
00488 break;
00489 case 'v':
00490 verbose = true;
00491 break;
00492
00493 case '?':
00494 puts( USAGE );
00495 exit(0);
00496 break;
00497 default:
00498 printf("unhandled option %c\n", ch );
00499 puts( USAGE );
00500
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("");
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
00526 av_init( host.c_str(), port, rootdir.c_str(), verbose, "AvonStage", version );
00527
00528
00529
00530
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
00541 av_install_clock_callbacks( (av_clock_get_t)GetTimeWorld, world );
00542
00543
00544 av_startup();
00545
00546
00547 world->ForEachDescendant( RegisterModel, NULL );
00548
00549 if( ! world->paused )
00550 world->Start();
00551
00552 while( 1 )
00553 {
00554
00555
00556 Fl::check();
00557 av_check();
00558
00559 usleep(100);
00560 }
00561
00562 puts( "\n[AvonStage: done]" );
00563
00564 return EXIT_SUCCESS;
00565 }