avonstage.cc
Go to the documentation of this file.
1 
7 #include <getopt.h>
8 
9 extern "C" {
10 #include <avon.h>
11 }
12 
13 #include "stage.hh"
14 #include "config.h"
15 
16 const char* AVONSTAGE_VERSION = "1.0.0";
17 
18 const char* USAGE =
19  "USAGE: stage [options] <worldfile1> [worldfile2 ... worldfileN]\n"
20  "Available [options] are:\n"
21  " --clock : print simulation time peridically on standard output\n"
22  " -c : equivalent to --clock\n"
23  " --gui : run without a GUI\n"
24  " -g : equivalent to --gui\n"
25  " --help : print this message\n"
26  " --args \"str\" : define an argument string to be passed to all controllers\n"
27  " -a \"str\" : equivalent to --args \"str\"\n"
28  " --host \"str\" : set the http server host name (default: \"localhost\")\n"
29  " --port num : set the http sever port number (default: 8000)\n"
30  " --verbose : provide lots of informative output\n"
31  " -v : equivalent to --verbose\n"
32  " -? : equivalent to --help\n";
33 
34 /* options descriptor */
35 static struct option longopts[] = {
36  { "gui", optional_argument, NULL, 'g' },
37  { "clock", optional_argument, NULL, 'c' },
38  { "help", optional_argument, NULL, 'h' },
39  { "args", required_argument, NULL, 'a' },
40  { "verbose", no_argument, NULL, 'v' },
41  { "port", required_argument, NULL, 'p' },
42  { "host", required_argument, NULL, 'h' },
43  { "rootdir", required_argument, NULL, 'r' },
44  { NULL, 0, NULL, 0 }
45 };
46 
47 
48 
49 uint64_t GetTimeWorld( Stg::World* world )
50 {
51  Stg::usec_t stgtime = world->SimTimeNow();
52  return static_cast<uint64_t>(stgtime);
53 }
54 
55 uint64_t GetTime( Stg::Model* mod )
56 {
57  assert(mod);
58  return GetTimeWorld( mod->GetWorld() );
59 }
60 
61 int GetModelPVA( Stg::Model* mod, av_pva_t* pva )
62 {
63  assert(mod);
64  assert(pva);
65 
66  bzero(pva,sizeof(av_pva_t));
67 
68  pva->time = GetTime(mod);
69 
70  Stg::Pose sp = mod->GetPose();
71 
72  pva->p[0] = sp.x;
73  pva->p[1] = sp.y;
74  pva->p[2] = sp.z;
75  pva->p[3] = 0;
76  pva->p[4] = 0;
77  pva->p[5] = sp.a;
78 
79  Stg::Velocity sv = mod->GetVelocity();
80 
81  pva->v[0] = sv.x;
82  pva->v[1] = sv.y;
83  pva->v[2] = sv.z;
84  pva->v[3] = 0;
85  pva->v[4] = 0;
86  pva->v[5] = sv.a;
87 
88  return 0; // ok
89 }
90 
91 
92 int SetModelPVA( Stg::Model* mod, av_pva_t* p )
93 {
94  assert(mod);
95  assert(p);
96 
97  mod->SetPose( Stg::Pose( p->p[0], // x
98  p->p[1], // y
99  p->p[2], // z
100  p->p[5] )); // a
101 
102  mod->SetVelocity( Stg::Velocity( p->v[0], // x
103  p->v[1], // y
104  p->v[2], // z
105  p->v[5] )); // a
106  return 0; // ok
107 }
108 
109 
110 int SetModelGeom( Stg::Model* mod, av_geom_t* g )
111 {
112  assert(mod);
113  assert(g);
114 
115  mod->SetGeom( Stg::Geom( Stg::Pose(g->pose[0],
116  g->pose[1],
117  g->pose[2],
118  g->pose[5] ),
119  Stg::Size(g->extent[0],
120  g->extent[1],
121  g->extent[2] )));
122 
123  // force GUI update to see the change if Stage was paused
124  mod->Redraw();
125 
126  return 0; // ok
127 }
128 
129 int GetModelGeom( Stg::Model* mod, av_geom_t* g )
130 {
131  assert(mod);
132  assert(g);
133 
134  bzero(g, sizeof(av_geom_t));
135 
136  g->time = GetTime(mod);
137 
138  Stg::Geom ext(mod->GetGeom());
139  g->pose[0] = ext.pose.x;
140  g->pose[1] = ext.pose.y;
141  g->pose[2] = ext.pose.a;
142  g->extent[0] = ext.size.x;
143  g->extent[1] = ext.size.y;
144  g->extent[2] = ext.size.z;
145 
146  return 0; // ok
147 }
148 
149 
150 int RangerData( Stg::Model* mod, av_msg_t* data )
151 {
152  assert(mod);
153  assert(data);
154 
155  if( ! mod->HasSubscribers() )
156  mod->Subscribe();
157 
158  /* Will set the data pointer in arg data to point to this static
159  struct, thus avoiding dynamic memory allocation. This is deeply
160  non-reentrant! but fast and simple code. */
161  static av_ranger_data_t rd;
162  bzero(&rd, sizeof(rd));
163  bzero(data, sizeof(av_msg_t));
164 
165  data->time = GetTime(mod);
166  data->interface = AV_INTERFACE_RANGER;
167  data->data = (const void*)&rd;
168 
169  Stg::ModelRanger* r = dynamic_cast<Stg::ModelRanger*>(mod);
170 
171  const std::vector<Stg::ModelRanger::Sensor>& sensors = r->GetSensors();
172 
173  rd.transducer_count = sensors.size();
174 
175  assert( rd.transducer_count <= AV_RANGER_TRANSDUCERS_MAX );
176 
177  rd.time = data->time;
178 
179 
180  return 0; //ok
181 }
182 
183 
184 int RangerSet( Stg::Model* mod, av_msg_t* data )
185 {
186  assert(mod);
187  assert(data);
188  puts( "ranger set does nothing" );
189  return 0; //ok
190 }
191 
192 int RangerGet( Stg::Model* mod, av_msg_t* data )
193 {
194  assert(mod);
195  assert(data);
196 
197  static av_ranger_t rgr;
198  bzero(&rgr,sizeof(rgr));
199 
200  data->time = GetTime(mod);
201  data->interface = AV_INTERFACE_RANGER;
202  data->data = (const void*)&rgr;
203 
204  rgr.time = data->time;
205 
206  Stg::ModelRanger* r = dynamic_cast<Stg::ModelRanger*>(mod);
207 
208  const std::vector<Stg::ModelRanger::Sensor>& sensors = r->GetSensors();
209 
210  rgr.transducer_count = sensors.size();
211 
212  assert( rgr.transducer_count <= AV_RANGER_TRANSDUCERS_MAX );
213 
214 
215  for( unsigned int c=0; c<rgr.transducer_count; c++ )
216  {
217  // bearing
218  rgr.transducers[c].fov[0].min = -sensors[c].fov/2.0;
219  rgr.transducers[c].fov[0].max = sensors[c].fov/2.0;
220 
221  //azimuth
222  rgr.transducers[c].fov[1].min = 0.0;
223  rgr.transducers[c].fov[1].max = 0.0;
224 
225  // range
226  rgr.transducers[c].fov[2].min = sensors[c].range.min;
227  rgr.transducers[c].fov[2].min = sensors[c].range.max;
228 
229  // pose 6dof
230  rgr.transducers[c].geom.pose[0] = sensors[c].pose.x;
231  rgr.transducers[c].geom.pose[1] = sensors[c].pose.y;
232  rgr.transducers[c].geom.pose[2] = sensors[c].pose.z;
233  rgr.transducers[c].geom.pose[3] = 0.0;
234  rgr.transducers[c].geom.pose[4] = 0.0;
235  rgr.transducers[c].geom.pose[5] = sensors[c].pose.a;
236 
237  // extent 3dof
238  rgr.transducers[c].geom.extent[0] = sensors[c].size.x;
239  rgr.transducers[c].geom.extent[1] = sensors[c].size.y;
240  rgr.transducers[c].geom.extent[2] = sensors[c].size.z;
241 
242 
243  av_ranger_transducer_data_t& t = rgr.transducers[c];
244  const Stg::ModelRanger::Sensor& s = sensors[c];
245 
246  t.pose[0] = s.pose.x;
247  t.pose[1] = s.pose.y;
248  t.pose[2] = s.pose.z;
249  t.pose[3] = 0.0;
250  t.pose[4] = 0.0;
251  t.pose[5] = s.pose.a;
252 
253  const std::vector<Stg::meters_t>& ranges = s.ranges;
254  const std::vector<double>& intensities = s.intensities;
255 
256  assert( ranges.size() == intensities.size() );
257 
258  t.sample_count = ranges.size();
259 
260  const double fov_max = s.fov / 2.0;
261  const double fov_min = -fov_max;
262  const double delta = (fov_max - fov_min) / (double)t.sample_count;
263 
264  for( unsigned int r=0; r<t.sample_count; r++ )
265  {
266  t.samples[r][AV_SAMPLE_BEARING] = fov_min + r*delta;
267  t.samples[r][AV_SAMPLE_AZIMUTH] = 0.0; // linear scanner
268  t.samples[r][AV_SAMPLE_RANGE] = ranges[r];
269  t.samples[r][AV_SAMPLE_INTENSITY] = intensities[r];
270  }
271  }
272  return 0; //ok
273 }
274 
275 
276 int FiducialData( Stg::Model* mod, av_msg_t* data )
277 {
278  assert(mod);
279  assert(data);
280 
281  if( ! mod->HasSubscribers() )
282  mod->Subscribe();
283 
284  /* Will set the data pointer in arg data to point to this static
285  struct, thus avoiding dynamic memory allocation. This is deeply
286  non-reentrant! but fast and simple code. */
287  static av_fiducial_data_t fd;
288  bzero(&fd, sizeof(fd));
289  bzero(data, sizeof(av_msg_t));
290 
291  data->time = GetTime(mod);
292  data->interface = AV_INTERFACE_FIDUCIAL;
293  data->data = (const void*)&fd;
294 
295  Stg::ModelFiducial* fm = dynamic_cast<Stg::ModelFiducial*>(mod);
296 
297  const std::vector<Stg::ModelFiducial::Fiducial>& sf = fm->GetFiducials();
298 
299  fd.fiducial_count = sf.size();
300 
301  printf( "FIDUCIALS %u\n", fd.fiducial_count );
302 
303  for( size_t i=0; i<fd.fiducial_count; i++ )
304  {
305  fd.fiducials[i].pose[0] = sf[i].bearing;
306  fd.fiducials[i].pose[1] = 0.0; // no azimuth in Stage
307  fd.fiducials[i].pose[2] = sf[i].range;
308 
309  fd.fiducials[i].geom.pose[0] = 0.0; // sf[i].pose_rel.x;
310  fd.fiducials[i].geom.pose[1] = 0.0; // sf[i].pose_rel.y;
311  fd.fiducials[i].geom.pose[2] = 0.0;
312  fd.fiducials[i].geom.pose[3] = 0.0;
313  fd.fiducials[i].geom.pose[4] = 0.0;
314  fd.fiducials[i].geom.pose[5] = sf[i].geom.a;
315 
316  fd.fiducials[i].geom.extent[0] = sf[i].geom.x;
317  fd.fiducials[i].geom.extent[1] = sf[i].geom.y;
318  fd.fiducials[i].geom.extent[2] = sf[i].geom.z;
319  }
320 
321  return 0;
322 }
323 
324 
325 int FiducialSet( Stg::Model* mod, av_msg_t* data )
326 {
327  assert(mod);
328  assert(data);
329  puts( "fiducial setcfg does nothing" );
330  return 0; //ok
331 }
332 
333 
334 int FiducialGet( Stg::Model* mod, av_msg_t* msg )
335 {
336  assert(mod);
337  assert(msg);
338 
339  static av_fiducial_cfg_t cfg;
340  bzero(&cfg,sizeof(cfg));
341 
342  msg->time = GetTime(mod);
343  msg->interface = AV_INTERFACE_FIDUCIAL;
344  msg->data = (const void*)&cfg;
345 
346  // cfg.time = msg->time;
347 
348  Stg::ModelFiducial* fid = dynamic_cast<Stg::ModelFiducial*>(mod);
349 
350  // bearing
351  cfg.fov[0].min = -fid->fov/2.0;
352  cfg.fov[0].max = fid->fov/2.0;
353 
354  // azimuth
355  cfg.fov[1].min = 0;
356  cfg.fov[1].max = 0;
357 
358  // range
359  cfg.fov[2].min = fid->min_range;
360  cfg.fov[2].max = fid->max_range_anon;
361 
362  return 0; // ok
363 }
364 
365 
366 class Reg
367 {
368 public:
369  std::string prototype;
370  av_interface_t interface;
371  av_prop_get_t getter;
372  av_prop_set_t setter;
373 
374  Reg( const std::string& prototype,
375  av_interface_t interface,
376  av_prop_get_t getter,
377  av_prop_set_t setter ) :
378  prototype(prototype),
379  interface(interface),
380  getter(getter),
381  setter(setter)
382  {}
383 };
384 
385 std::pair<std::string,av_interface_t> proto_iface_pair_t;
386 
387 int RegisterModel( Stg::Model* mod, void* dummy )
388 {
389  // expensive to test this here! XX todo optmize this for large pops
390  if( mod->TokenStr() == "_ground_model" )
391  return 0;
392 
393  static std::map<std::string,Reg> type_table;
394 
395  if( type_table.size() == 0 ) // first call only
396  {
397  type_table[ "model" ] =
398  Reg( "generic", AV_INTERFACE_GENERIC,NULL,NULL );
399 
400  type_table[ "position" ] =
401  Reg( "position2d", AV_INTERFACE_GENERIC,NULL,NULL );
402 
403  type_table[ "ranger" ] =
404  Reg( "ranger", AV_INTERFACE_RANGER, RangerGet, RangerSet );
405 
406  type_table[ "fiducial" ] =
407  Reg( "fiducial", AV_INTERFACE_FIDUCIA, FiducualGet, FiducualSet );
408  }
409 
410  printf( "[AvonStage] registering %s\n", mod->Token() );
411 
412  // look up the model type in the table
413 
414  const std::map<std::string,proto_iface_pair_t>::iterator it =
415  type_table.find( mod->GetModelType() );
416 
417  if( it != type_table.end() ) // if we found it in the table
418  {
419  Stg::Model* parent = mod->Parent();
420  const char* parent_name = parent ? parent->Token() : NULL;
421 
422  av_register_object( mod->Token(),
423  parent_name,
424  it->prototype.c_str(),
425  it->interface,
426  it->getter,
427  it->setter,
428  dynamic_cast<void*>(mod) );
429  return 0; // ok
430  }
431 
432  // else
433  printf( "Avonstage error: model type \"%s\" not found.\n",
434  mod->GetModelType().c_str() );
435  return 1; //fail
436 }
437 
438 int main( int argc, char* argv[] )
439 {
440  // initialize libstage - call this first
441  Stg::Init( &argc, &argv );
442 
443  printf( "%s %s ", PROJECT, VERSION );
444 
445  int ch=0, optindex=0;
446  bool usegui = true;
447  bool showclock = false;
448 
449  std::string host = "localhost";
450  std::string rootdir = ".";
451  unsigned short port = AV_DEFAULT_PORT;
452  bool verbose = false;
453 
454  while ((ch = getopt_long(argc, argv, "cvrgh?p?", longopts, &optindex)) != -1)
455  {
456  switch( ch )
457  {
458  case 0: // long option given
459  printf( "option %s given\n", longopts[optindex].name );
460  break;
461 
462  // stage options
463  case 'a':
464  Stg::World::ctrlargs = std::string(optarg);
465  break;
466  case 'c':
467  showclock = true;
468  printf( "[Clock enabled]" );
469  break;
470  case 'g':
471  usegui = false;
472  printf( "[GUI disabled]" );
473  break;
474 
475  // avon options
476  case 'p':
477  port = atoi(optarg);
478  break;
479  case 'h':
480  host = std::string(optarg);
481  break;
482  // case 'f':
483  // fedfilename = optarg;
484  // usefedfile = true;
485  // break;
486  case 'r':
487  rootdir = std::string(optarg);
488  break;
489  case 'v':
490  verbose = true;
491  break;
492  // help options
493  case '?':
494  puts( USAGE );
495  exit(0);
496  break;
497  default:
498  printf("unhandled option %c\n", ch );
499  puts( USAGE );
500  //exit(0);
501  }
502  }
503 
504  const char* worldfilename = argv[optind];
505 
506  if( worldfilename == NULL )
507  {
508  puts( "[AvonStage] no worldfile specified on command line. Quit.\n" );
509  exit(-1);
510  }
511 
512  puts("");// end the first start-up line
513 
514  printf( "[AvonStage] host %s:%u world %s\n",
515  host.c_str(),
516  port,
517  worldfilename );
518 
519  char version[1024];
520  snprintf( version, 1024, "%s (%s-%s)",
522  PROJECT,
523  VERSION );
524 
525  // avon
526  av_init( host.c_str(), port, rootdir.c_str(), verbose, "AvonStage", version );
527 
528 
529  // arguments at index [optindex] and later are not options, so they
530  // must be world file names
531 
532 
533  Stg::World* world = ( usegui ?
534  new Stg::WorldGui( 400, 300, worldfilename ) :
535  new Stg::World( worldfilename ) );
536 
537  world->Load( worldfilename );
538  world->ShowClock( showclock );
539 
540  // now we have a world object, we can install a clock callback
541  av_install_clock_callbacks( (av_clock_get_t)GetTimeWorld, world );
542 
543  // start the http server
544  av_startup();
545 
546  // register all models here
547  world->ForEachDescendant( RegisterModel, NULL );
548 
549  if( ! world->paused )
550  world->Start();
551 
552  while( 1 )
553  {
554  // TODO - loop properly
555 
556  Fl::check();
557  av_check();
558 
559  usleep(100); // TODO - loop sensibly here
560  }
561 
562  puts( "\n[AvonStage: done]" );
563 
564  return EXIT_SUCCESS;
565 }
radians_t fov
field of view
Definition: stage.hh:2727
Model class
Definition: stage.hh:1742
meters_t max_range_anon
maximum detection range
Definition: stage.hh:2724
Model * Parent() const
Definition: stage.hh:2299
int RangerGet(Stg::Model *mod, av_msg_t *data)
Definition: avonstage.cc:192
int GetModelGeom(Stg::Model *mod, av_geom_t *g)
Definition: avonstage.cc:129
av_interface_t interface
Definition: avonstage.cc:370
usec_t SimTimeNow(void) const
Definition: stage.hh:1119
World class
Definition: stage.hh:814
std::vector< Fiducial > & GetFiducials()
Definition: stage.hh:2733
void SetPose(const Pose &pose)
Definition: model.cc:1396
int RegisterModel(Stg::Model *mod, void *dummy)
Definition: avonstage.cc:387
void Init(int *argc, char **argv[])
Definition: stage.cc:18
int SetModelPVA(Stg::Model *mod, av_pva_t *p)
Definition: avonstage.cc:92
std::pair< std::string, av_interface_t > proto_iface_pair_t
Definition: avonstage.cc:385
Reg(const std::string &prototype, av_interface_t interface, av_prop_get_t getter, av_prop_set_t setter)
Definition: avonstage.cc:374
float s
Definition: glutgraphics.cc:58
World * GetWorld() const
Definition: stage.hh:2302
meters_t z
location in 3 axes
Definition: stage.hh:251
meters_t y
Definition: stage.hh:251
static int argc
uint64_t GetTime(Stg::Model *mod)
Definition: avonstage.cc:55
const char * USAGE
Definition: avonstage.cc:18
Pose pose
position
Definition: stage.hh:394
uint64_t GetTimeWorld(Stg::World *world)
Definition: avonstage.cc:49
av_prop_set_t setter
Definition: avonstage.cc:372
uint64_t usec_t
Definition: stage.hh:186
int FiducialData(Stg::Model *mod, av_msg_t *data)
Definition: avonstage.cc:276
int SetModelGeom(Stg::Model *mod, av_geom_t *g)
Definition: avonstage.cc:110
int main(int argc, char *argv[])
Definition: avonstage.cc:438
const std::vector< Sensor > & GetSensors() const
Definition: stage.hh:2804
int RangerData(Stg::Model *mod, av_msg_t *data)
Definition: avonstage.cc:150
int GetModelPVA(Stg::Model *mod, av_pva_t *pva)
Definition: avonstage.cc:61
void Redraw()
Definition: model.cc:909
void Subscribe()
Definition: model.cc:646
int RangerSet(Stg::Model *mod, av_msg_t *data)
Definition: avonstage.cc:184
int FiducialGet(Stg::Model *mod, av_msg_t *msg)
Definition: avonstage.cc:334
static char * argv
ModelFiducial class
Definition: stage.hh:2687
static struct option longopts[]
Definition: avonstage.cc:35
ModelRanger class
Definition: stage.hh:2747
const bool verbose
Definition: fasr.cc:4
const std::string & TokenStr() const
Definition: stage.hh:716
bool HasSubscribers() const
Definition: stage.hh:2464
void SetGeom(const Geom &src)
Definition: model.cc:1243
av_prop_get_t getter
Definition: avonstage.cc:371
std::string prototype
Definition: avonstage.cc:369
Pose GetPose() const
Definition: stage.hh:2382
radians_t a
rotation about the z axis.
Definition: stage.hh:252
meters_t min_range
minimum detection range
Definition: stage.hh:2726
std::vector< meters_t > ranges
Definition: stage.hh:2782
const std::string & GetModelType() const
Definition: stage.hh:2036
std::vector< double > intensities
Definition: stage.hh:2783
static std::string ctrlargs
Definition: stage.hh:827
meters_t x
Definition: stage.hh:251
const char * Token() const
Definition: stage.hh:715
int FiducialSet(Stg::Model *mod, av_msg_t *data)
Definition: avonstage.cc:325
const char * AVONSTAGE_VERSION
Definition: avonstage.cc:16
virtual void Load(const std::string &worldfile_path)
Definition: world.cc:388
Geom GetGeom() const
Definition: stage.hh:2378


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 Mon Jun 10 2019 15:06:09