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


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 Feb 28 2022 23:48:55