model.cc
Go to the documentation of this file.
1 
131 #ifndef _GNU_SOURCE
132 #define _GNU_SOURCE
133 #endif
134 
135 #include <ltdl.h> // for library module loading
136 #include <map>
137 #include <sstream> // for converting values to strings
138 
139 #include "config.h" // for build-time config
140 #include "file_manager.hh"
141 #include "stage.hh"
142 #include "worldfile.hh"
143 using namespace Stg;
144 
145 // static members
146 uint32_t Model::count(0);
147 std::map<Stg::id_t, Model *> Model::modelsbyid;
148 std::map<std::string, creator_t> Model::name_map;
149 
150 // static const members
151 static const double DEFAULT_FRICTION = 0.0;
152 
153 Bounds &Bounds::Load(Worldfile *wf, const int section, const char *keyword)
154 {
155  wf->ReadTuple(section, keyword, 0, 2, "ll", &min, &max);
156  return *this;
157 }
158 
159 double Bounds::Constrain(double value)
160 {
161  return Stg::constrain(value, min, max);
162 }
163 
164 Stg::Size &Stg::Size::Load(Worldfile *wf, const int section, const char *keyword)
165 {
166  wf->ReadTuple(section, keyword, 0, 3, "lll", &x, &y, &z);
167  return *this;
168 }
169 
170 void Stg::Size::Save(Worldfile *wf, int section, const char *keyword) const
171 {
172  wf->WriteTuple(section, keyword, 0, 3, "lll", x, y, z);
173 }
174 
175 Pose &Pose::Load(Worldfile *wf, const int section, const char *keyword)
176 {
177  wf->ReadTuple(section, keyword, 0, 4, "llla", &x, &y, &z, &a);
178  normalize(a);
179  return *this;
180 }
181 
182 void Pose::Save(Worldfile *wf, const int section, const char *keyword)
183 {
184  wf->WriteTuple(section, keyword, 0, 4, "llla", x, y, z, a);
185 }
186 
188  : blob_return(true), fiducial_key(0), fiducial_return(0), gripper_return(false),
189  obstacle_return(true), ranger_return(1.0)
190 { /* nothing to do */
191 }
192 
194 {
195  blob_return = wf->ReadInt(wf_entity, "blob_return", blob_return);
196  fiducial_key = wf->ReadInt(wf_entity, "fiducial_key", fiducial_key);
197  fiducial_return = wf->ReadInt(wf_entity, "fiducial_return", fiducial_return);
198  gripper_return = wf->ReadInt(wf_entity, "gripper_return", gripper_return);
199  obstacle_return = wf->ReadInt(wf_entity, "obstacle_return", obstacle_return);
200  ranger_return = wf->ReadFloat(wf_entity, "ranger_return", ranger_return);
201 
202  return *this;
203 }
204 
206 {
207  wf->WriteInt(wf_entity, "blob_return", blob_return);
208  wf->WriteInt(wf_entity, "fiducial_key", fiducial_key);
209  wf->WriteInt(wf_entity, "fiducial_return", fiducial_return);
210  wf->WriteInt(wf_entity, "gripper_return", gripper_return);
211  wf->WriteInt(wf_entity, "obstacle_return", obstacle_return);
212  wf->WriteFloat(wf_entity, "ranger_return", ranger_return);
213 }
214 
215 Model::GuiState::GuiState() : grid(false), move(false), nose(false), outline(false)
216 { /* nothing to do */
217 }
218 
220 {
221  nose = wf->ReadInt(wf_entity, "gui_nose", nose);
222  grid = wf->ReadInt(wf_entity, "gui_grid", grid);
223  outline = wf->ReadInt(wf_entity, "gui_outline", outline);
224  move = wf->ReadInt(wf_entity, "gui_move", move);
225 
226  return *this;
227 }
228 
229 // constructor
230 Model::Model(World *world, Model *parent, const std::string &type, const std::string &name)
231  : Ancestor(), mapped(false), drawOptions(), alwayson(false), blockgroup(*this), boundary(false),
232  callbacks(__CB_TYPE_COUNT), // one slot in the vector for each type
233  color(1, 0, 0), // red
235  geom(), has_default_block(true), id(Model::count++), interval((usec_t)1e5), // 100msec
236  interval_energy((usec_t)1e5), // 100msec
237  last_update(0), log_state(false), map_resolution(0.1), mass(0), parent(parent), pose(),
239  stack_children(true), stall(false), subs(0), thread_safe(false), trail(20),
240  trail_index(0), trail_interval(10), type(type), event_queue_num(0), used(false), watts(0.0), watts_give(0.0),
241  watts_take(0.0), wf(NULL), wf_entity(0), world(world),
242  world_gui(dynamic_cast<WorldGui *>(world))
243 {
244  assert(world);
245 
246  PRINT_DEBUG3("Constructing model world: %s parent: %s type: %s \n", world->Token(),
247  parent ? parent->Token() : "(null)", type.c_str());
248 
249  modelsbyid[id] = this;
250 
251  if (name.size()) // use a name if specified
252  {
253  // printf( "name set %s\n", name.c_str() );
254  SetToken(name);
255  } else // if a name was not specified make up a name based on the parent's
256  // name, model type and the number of instances so far
257  {
258  char buf[2048];
259  // printf( "adding child of type %d token %s\n", mod->type, mod->Token() );
260 
261  // prefix with parent name if any, followed by the type name
262  // with a suffix of a colon and the parent's number of children
263  // of this type
264  if (parent) {
265  snprintf(buf, 2048, "%s.%s:%u", parent->Token(), type.c_str(),
266  parent->child_type_counts[type]);
267  } else // no parent, so use the count of this type in the world
268  {
269  snprintf(buf, 2048, "%s:%u", type.c_str(), world->child_type_counts[type]);
270  }
271 
272  // printf( "generated name %s\n", buf );
273  SetToken(buf);
274  }
275 
276  // printf( "%s generated a name for my child %s\n", Token(),
277  // name.str().c_str() );
278 
279  world->AddModel(this);
280 
281  if (parent)
282  parent->AddChild(this);
283  else {
284  world->AddChild(this);
285  // top level models are draggable in the GUI by default
286  gui.move = true;
287  }
288 
289  //static size_t count=0;
290  //printf( "basic %lu\n", ++count );
291 
292  // now we can add the basic square shape
293  AddBlockRect(-0.5, -0.5, 1.0, 1.0, 1.0);
294 
295  AddVisualizer(&rastervis, false);
296 
297  PRINT_DEBUG2("finished model %s @ %p", this->Token(), this);
298 }
299 
301 {
302  // children are removed in ancestor class
303 
304  if (world) // if I'm not a worldless dummy model
305  {
306  UnMap(); // remove from all layers
307 
308  // remove myself from my parent's child list, or the world's child
309  // list if I have no parent
311  // erase from the static map of all models
312  modelsbyid.erase(id);
313 
314  world->RemoveModel(this);
315  }
316 }
317 
319 {
321 }
322 
323 void Model::AddFlag(Flag *flag)
324 {
325  if (flag) {
326  flag_list.push_back(flag);
328  }
329 }
330 
332 {
333  if (flag) {
334  EraseAll(flag, flag_list);
336  }
337 }
338 
340 {
341  if (flag) {
342  flag_list.push_front(flag);
344  }
345 }
346 
348 {
349  if (flag_list.size() == 0)
350  return NULL;
351 
352  Flag *flag = flag_list.front();
353  flag_list.pop_front();
354 
356 
357  return flag;
358 }
359 
361 {
362  UnMap();
363  blockgroup.Clear();
364  // no need to Map() - we have no blocks
365  NeedRedraw();
366 }
367 
368 void Model::LoadBlock(Worldfile *wf, int entity)
369 {
370  if (has_default_block) {
371  blockgroup.Clear();
372  has_default_block = false;
373  }
374 
375  blockgroup.LoadBlock(wf, entity);
376 }
377 
379 {
380  UnMap();
381 
382  std::vector<point_t> pts(4);
383  pts[0].x = x;
384  pts[0].y = y;
385  pts[1].x = x + dx;
386  pts[1].y = y;
387  pts[2].x = x + dx;
388  pts[2].y = y + dy;
389  pts[3].x = x;
390  pts[3].y = y + dy;
391 
392  blockgroup.AppendBlock(Block(&blockgroup, pts, Bounds(0, dz)));
393 
394  Map();
395 }
396 
397 // convert a global pose into the model's local coordinate system
399 {
400  // get model's global pose
401  const Pose org(GetGlobalPose());
402  const double cosa(cos(org.a));
403  const double sina(sin(org.a));
404 
405  // compute global pose in local coords
406  return Pose((pose.x - org.x) * cosa + (pose.y - org.y) * sina,
407  -(pose.x - org.x) * sina + (pose.y - org.y) * cosa, pose.z - org.z, pose.a - org.a);
408 }
409 
410 void Model::Say(const std::string &str)
411 {
412  say_string = str;
413 }
414 
415 // returns true iff model [testmod] is an antecedent of this model
416 bool Model::IsAntecedent(const Model *testmod) const
417 {
418  if (parent == NULL)
419  return false;
420 
421  if (parent == testmod)
422  return true;
423 
424  return parent->IsAntecedent(testmod);
425 }
426 
427 // returns true iff model [testmod] is a descendent of this model
428 bool Model::IsDescendent(const Model *testmod) const
429 {
430  if (this == testmod)
431  return true;
432 
433  FOR_EACH (it, children)
434  if ((*it)->IsDescendent(testmod))
435  return true;
436 
437  // neither mod nor a child of this matches testmod
438  return false;
439 }
440 
441 bool Model::IsRelated(const Model *that) const
442 {
443  // is it me?
444  if (this == that)
445  return true;
446 
447  // wind up to top-level object
448  const Model *candidate = this;
449  while (candidate->parent) {
450  // shortcut out if we found it on the way up the tree
451  if (candidate->parent == that)
452  return true;
453 
454  candidate = candidate->parent;
455  }
456 
457  // we got to our root, so recurse down the tree
458  return candidate->IsDescendent(that);
459  // TODO: recursive solution is costing us 3% of all compute time! try an
460  // iterative solution?
461 }
462 
464 {
465  const Pose gpose = LocalToGlobal(Pose(pt.x, pt.y, 0, 0));
466  return point_t(gpose.x, gpose.y);
467 }
468 
469 std::vector<point_int_t> Model::LocalToPixels(const std::vector<point_t> &local) const
470 {
471  const size_t sz = local.size();
472 
473  std::vector<point_int_t> global(sz);
474 
475  const Pose gpose(GetGlobalPose() + geom.pose);
476  Pose ptpose;
477 
478  for (size_t i = 0; i < sz; i++) {
479  ptpose = gpose + Pose(local[i].x, local[i].y, 0, 0);
480 
481  global[i].x = (int32_t)floor(ptpose.x * world->ppm);
482  global[i].y = (int32_t)floor(ptpose.y * world->ppm);
483  }
484 
485  return global;
486 }
487 
488 void Model::MapWithChildren(unsigned int layer)
489 {
490  Map(layer);
491 
492  // recursive call for all the model's children
493  FOR_EACH (it, children)
494  (*it)->MapWithChildren(layer);
495 }
496 
497 void Model::MapFromRoot(unsigned int layer)
498 {
499  Root()->MapWithChildren(layer);
500 }
501 
502 void Model::UnMapWithChildren(unsigned int layer)
503 {
504  UnMap(layer);
505 
506  // recursive call for all the model's children
507  FOR_EACH (it, children)
508  (*it)->UnMapWithChildren(layer);
509 }
510 
511 void Model::UnMapFromRoot(unsigned int layer)
512 {
513  Root()->UnMapWithChildren(layer);
514 }
515 
517 {
518  subs++;
519  world->total_subs++;
520  world->dirty = true; // need redraw
521 
522  // printf( "subscribe to %s %d\n", Token(), subs );
523 
524  // if this is the first sub, call startup
525  if (subs == 1)
526  Startup();
527 }
528 
530 {
531  subs--;
532  world->total_subs--;
533  world->dirty = true; // need redraw
534 
535  // printf( "unsubscribe from %s %d\n", Token(), subs );
536 
537  // if this is the last remaining subscriber, shutdown
538  if (subs == 0)
539  Shutdown();
540 }
541 
542 void Model::Print(char *prefix) const
543 {
544  if (prefix)
545  printf("%s model ", prefix);
546  else
547  printf("Model ");
548 
549  printf("%s:%s\n", world->Token(), Token());
550 
551  FOR_EACH (it, children)
552  (*it)->Print(prefix);
553 }
554 
555 const char *Model::PrintWithPose() const
556 {
557  const Pose gpose = GetGlobalPose();
558 
559  static char txt[256];
560  snprintf(txt, sizeof(txt), "%s @ [%.2f,%.2f,%.2f,%.2f]", Token(), gpose.x, gpose.y, gpose.z,
561  gpose.a);
562 
563  return txt;
564 }
565 
566 void Model::Startup(void)
567 {
568  // printf( "Startup model %s\n", this->token );
569  // printf( "model %s using queue %d\n", token, event_queue_num );
570 
571  // iff we're thread safe, we can use an event queue >0, else 0
573 
575 
576  if (FindPowerPack())
577  world->EnableEnergy(this);
578 
580 }
581 
582 void Model::Shutdown(void)
583 {
584  // printf( "Shutdown model %s\n", this->token );
586 
587  world->DisableEnergy(this);
588 
589  // allows data visualizations to be cleared.
590  NeedRedraw();
591 }
592 
593 void Model::Update(void)
594 {
595  // printf( "Q%d model %p %s update\n", event_queue_num, this, Token() );
596 
598 
599  if (subs > 0) // no subscriptions means we don't need to be updated
601 
602  // if we updated the model then it needs to have its update
603  // callback called in series back in the main thread. It's
604  // not safe to run user callbacks in a worker thread, as
605  // they may make OpenGL calls or unsafe Stage API calls,
606  // etc. We queue up the callback into a queue specific to
607 
608  if (!callbacks[Model::CB_UPDATE].empty())
610 }
611 
613 {
615 }
616 
618 {
619  meters_t m_child = 0; // max size of any child
620  FOR_EACH (it, children)
621  m_child = std::max(m_child, (*it)->ModelHeight());
622 
623  // height of model + max( child height )
624  return geom.size.z + m_child;
625 }
626 
627 void Model::AddToPose(double dx, double dy, double dz, double da)
628 {
629  Pose p(pose);
630  p.x += dx;
631  p.y += dy;
632  p.z += dz;
633  p.a += da;
634 
635  SetPose(p);
636 }
637 
639 {
640  AddToPose(pose.x, pose.y, pose.z, pose.a);
641 }
642 
643 
645  meters_t ymin, meters_t ymax,
646  size_t max_iter)
647 {
648  SetPose(Pose::Random(xmin, xmax, ymin, ymax));
649 
650  size_t i = 0;
651  while (TestCollision() && (max_iter <= 0 || i++ < max_iter))
652  SetPose(Pose::Random(xmin, xmax, ymin, ymax));
653  return i <= max_iter; // return true if a free pose was found within max iterations
654 }
655 
656 void Model::AppendTouchingModels(std::set<Model *> &touchers)
657 {
659 }
660 
662 {
663  Model *hitmod(blockgroup.TestCollision());
664 
665  if (hitmod == NULL)
666  FOR_EACH (it, children) {
667  hitmod = (*it)->TestCollision();
668  if (hitmod)
669  break;
670  }
671 
672  // printf( "mod %s test collision done.\n", token );
673  return hitmod;
674 }
675 
677 {
678  PowerPack *mypp = FindPowerPack();
679  assert(mypp);
680 
681  if (watts > 0) // dissipation rate
682  {
683  // consume energy stored in the power pack
684  mypp->Dissipate(watts * (interval_energy * 1e-6), GetGlobalPose());
685  }
686 
687  if (watts_give > 0) // transmission to other powerpacks max rate
688  {
689  // detach charger from all the packs charged last time
690  FOR_EACH (it, pps_charging)
691  (*it)->ChargeStop();
692  pps_charging.clear();
693 
694  // run through and update all appropriate touchers
695  std::set<Model *> touchers;
696  AppendTouchingModels(touchers);
697 
698  FOR_EACH (it, touchers) {
699  Model *toucher = (*it);
700  PowerPack *hispp = toucher->FindPowerPack();
701 
702  if (hispp && toucher->watts_take > 0.0) {
703  // printf( " toucher %s can take up to %.2f wats\n",
704  // toucher->Token(), toucher->watts_take );
705 
706  const watts_t rate = std::min(watts_give, toucher->watts_take);
707  const joules_t amount = rate * interval_energy * 1e-6;
708 
709  // printf ( "moving %.2f joules from %s to %s\n",
710  // amount, token, toucher->token );
711 
712  // set his charging flag
713  hispp->ChargeStart();
714 
715  // move some joules from me to him
716  mypp->TransferTo(hispp, amount);
717 
718  // remember who we are charging so we can detatch next time
719  pps_charging.push_front(hispp);
720  }
721  }
722  }
723 }
724 
726 {
727  // get the current item and increment the counter
728  TrailItem *item = &trail[trail_index++];
729 
730  // record the current info
731  item->time = world->sim_time;
732  item->pose = GetGlobalPose();
733  item->color = color;
734 
735  // wrap around ring buffer
736  trail_index %= trail.size();
737 }
738 
739 Model *Model::GetUnsubscribedModelOfType(const std::string &type) const
740 {
741  if ((this->type == type) && (this->subs == 0))
742  return const_cast<Model *>(this); // discard const
743 
744  // this model is no use. try children recursively
745  FOR_EACH (it, children) {
746  Model *found = (*it)->GetUnsubscribedModelOfType(type);
747  if (found)
748  return found;
749  }
750 
751  // nothing matching below this model
752  return NULL;
753 }
754 
756 {
757  rebuild_displaylist = true;
758 
759  if (parent)
760  parent->NeedRedraw();
761  else
762  world->NeedRedraw();
763 }
764 
765 void Model::Redraw(void)
766 {
767  world->Redraw();
768 }
769 
771 {
772  // printf( "searching for type %d in model %s type %d\n", type, token,
773  // this->type );
774 
775  if ((this->type == type) && (!this->used)) {
776  this->used = true;
777  return this;
778  }
779 
780  // this model is no use. try children recursively
781  FOR_EACH (it, children) {
782  Model *found = (*it)->GetUnusedModelOfType(type);
783  if (found)
784  return found;
785  }
786 
787  // nothing matching below this model
788  if (!parent)
789  PRINT_WARN1("Request for unused model of type %s failed", type.c_str());
790  return NULL;
791 }
792 
794 {
795  kg_t sum = mass;
796 
797  FOR_EACH (it, children)
798  sum += (*it)->GetTotalMass();
799 
800  return sum;
801 }
802 
804 {
805  return (GetTotalMass() - mass);
806 }
807 
808 // render all blocks in the group at my global pose and size
809 void Model::Map(unsigned int layer)
810 {
811  blockgroup.Map(layer);
812 }
813 
814 void Model::UnMap(unsigned int layer)
815 {
816  blockgroup.UnMap(layer);
817 }
818 
820 {
821  if (child->parent)
822  child->parent->RemoveChild(child);
823  else
824  world->RemoveChild(child);
825 
826  child->parent = this;
827 
828  this->AddChild(child);
829 
830  world->dirty = true;
831 }
832 
834 {
835  if (power_pack)
836  return power_pack;
837 
838  if (parent)
839  return parent->FindPowerPack();
840 
841  return NULL;
842 }
843 
845 {
846  world->RegisterOption(opt);
847 }
848 
849 void Model::Rasterize(uint8_t *data, unsigned int width, unsigned int height, meters_t cellwidth,
850  meters_t cellheight)
851 {
853  blockgroup.Rasterize(data, width, height, cellwidth, cellheight);
854  rastervis.SetData(data, width, height, cellwidth, cellheight);
855 }
856 
858 {
859  this->friction = friction;
860 }
861 
862 Model *Model::GetChild(const std::string &modelname) const
863 {
864  // construct the full model name and look it up
865 
866  const std::string fullname = token + "." + modelname;
867 
868  Model *mod = world->GetModel(fullname);
869 
870  if (mod == NULL)
871  PRINT_WARN1("Model %s not found", fullname.c_str());
872 
873  return mod;
874 }
875 
876 //***************************************************************
877 // Raster data visualizer
878 //
880  : Visualizer("Rasterization", "raster_vis"), data(NULL), width(0), height(0), cellwidth(0),
881  cellheight(0), pts(), subs(0), used(0)
882 {
883 }
884 
886 {
887  (void)cam; // avoid warning about unused var
888 
889  if (data == NULL)
890  return;
891 
892  // go into world coordinates
893  glPushMatrix();
894  mod->PushColor(1, 0, 0, 0.5);
895 
897 
898  if (pts.size() > 0) {
899  glPushMatrix();
900  // Size sz = mod->blockgroup.GetSize();
901  // glTranslatef( -mod->geom.size.x / 2.0, -mod->geom.size.y/2.0, 0 );
902  // glScalef( mod->geom.size.x / sz.x, mod->geom.size.y / sz.y, 1 );
903 
904  // now we're in world meters coordinates
905  glPointSize(4);
906  glBegin(GL_POINTS);
907 
908  FOR_EACH (it, pts) {
909  point_t &pt = *it;
910  glVertex2f(pt.x, pt.y);
911 
912  char buf[128];
913  snprintf(buf, 127, "[%.2f x %.2f]", pt.x, pt.y);
914  Gl::draw_string(pt.x, pt.y, 0, buf);
915  }
916  glEnd();
917 
918  mod->PopColor();
919 
920  glPopMatrix();
921  }
922 
923  // go into bitmap pixel coords
924  glTranslatef(-mod->geom.size.x / 2.0, -mod->geom.size.y / 2.0, 0);
925  // glScalef( mod->geom.size.x / width, mod->geom.size.y / height, 1 );
926 
927  glScalef(cellwidth, cellheight, 1);
928 
929  mod->PushColor(0, 0, 0, 0.5);
930  glPolygonMode(GL_FRONT, GL_FILL);
931  for (unsigned int y = 0; y < height; ++y)
932  for (unsigned int x = 0; x < width; ++x) {
933  // printf( "[%u %u] ", x, y );
934  if (data[x + y * width])
935  glRectf(x, y, x + 1, y + 1);
936  }
937 
938  glTranslatef(0, 0, 0.01);
939 
940  mod->PushColor(0, 0, 0, 1);
941  glPolygonMode(GL_FRONT, GL_LINE);
942  for (unsigned int y = 0; y < height; ++y)
943  for (unsigned int x = 0; x < width; ++x) {
944  if (data[x + y * width])
945  glRectf(x, y, x + 1, y + 1);
946 
947  // char buf[128];
948  // snprintf( buf, 127, "[%u x %u]", x, y );
949  // Gl::draw_string( x, y, 0, buf );
950  }
951 
952  glPolygonMode(GL_FRONT, GL_FILL);
953 
954  mod->PopColor();
955  mod->PopColor();
956 
957  mod->PushColor(0, 0, 0, 1);
958  char buf[128];
959  snprintf(buf, 127, "[%u x %u]", width, height);
960  glTranslatef(0, 0, 0.01);
961  Gl::draw_string(1, height - 1, 0, buf);
962 
963  mod->PopColor();
964 
965  glPopMatrix();
966 }
967 
968 void Model::RasterVis::SetData(uint8_t *data, const unsigned int width, const unsigned int height,
969  const meters_t cellwidth, const meters_t cellheight)
970 {
971  // copy the raster for test visualization
972  if (this->data)
973  delete[] this->data;
974  size_t len = sizeof(uint8_t) * width * height;
975  // printf( "allocating %lu bytes\n", len );
976  this->data = new uint8_t[len];
977  memcpy(this->data, data, len);
978  this->width = width;
979  this->height = height;
980  this->cellwidth = cellwidth;
981  this->cellheight = cellheight;
982 }
983 
985 {
986  pts.push_back(point_t(x, y));
987 }
988 
990 {
991  pts.clear();
992 }
993 
994 Model::Flag::Flag(const Color &color, const double size) : color(color), size(size), displaylist(0)
995 {
996 }
997 
999 {
1000  Flag *piece = NULL;
1001 
1002  if (size > 0) {
1003  chunk = std::min(chunk, this->size);
1004  piece = new Flag(this->color, chunk);
1005  this->size -= chunk;
1006  }
1007 
1008  return piece;
1009 }
1010 
1012 {
1013  color = c;
1014 
1015  if (displaylist) {
1016  // force recreation of list
1017  glDeleteLists(displaylist, 1);
1018  displaylist = 0;
1019  }
1020 }
1021 
1022 void Model::Flag::SetSize(double sz)
1023 {
1024  size = sz;
1025 
1026  if (displaylist) {
1027  // force recreation of list
1028  glDeleteLists(displaylist, 1);
1029  displaylist = 0;
1030  }
1031 }
1032 
1033 void Model::Flag::Draw(GLUquadric *quadric)
1034 {
1035  if (displaylist == 0) {
1036  displaylist = glGenLists(1);
1037  assert(displaylist > 0);
1038 
1039  glNewList(displaylist, GL_COMPILE);
1040 
1041  glColor4f(color.r, color.g, color.b, color.a);
1042 
1043  glEnable(GL_POLYGON_OFFSET_FILL);
1044  glPolygonOffset(1.0, 1.0);
1045  gluQuadricDrawStyle(quadric, GLU_FILL);
1046  gluSphere(quadric, size / 2.0, 4, 2);
1047  glDisable(GL_POLYGON_OFFSET_FILL);
1048 
1049  // draw the edges darker version of the same color
1050  glColor4f(color.r / 2.0, color.g / 2.0, color.b / 2.0, color.a / 2.0);
1051 
1052  gluQuadricDrawStyle(quadric, GLU_LINE);
1053  gluSphere(quadric, size / 2.0, 4, 2);
1054 
1055  glEndList();
1056  }
1057 
1058  glCallList(displaylist);
1059 }
1060 
1061 void Model::SetGeom(const Geom &val)
1062 {
1063  UnMapWithChildren(0);
1064  UnMapWithChildren(1);
1065 
1066  geom = val;
1067 
1068  blockgroup.CalcSize();
1069 
1070  // printf( "model %s SetGeom size [%.3f %.3f %.3f]\n", Token(), geom.size.x,
1071  // geom.size.y, geom.size.z );
1072 
1073  NeedRedraw();
1074 
1075  MapWithChildren(0);
1076  MapWithChildren(1);
1077 
1079 }
1080 
1082 {
1083  color = val;
1084  NeedRedraw();
1085 }
1086 
1088 {
1089  mass = val;
1090 }
1091 
1092 void Model::SetStall(bool val)
1093 {
1094  stall = val;
1095 }
1096 
1098 {
1099  vis.gripper_return = val;
1100 }
1101 
1103 {
1104  vis.fiducial_return = val;
1105 
1106  // non-zero values mean we need to be in the world's set of
1107  // detectable models
1108  if (val == 0)
1109  world->FiducialErase(this);
1110  else
1111  world->FiducialInsert(this);
1112 }
1113 
1115 {
1116  vis.fiducial_key = val;
1117 }
1118 
1120 {
1121  vis.obstacle_return = val;
1122 }
1123 
1124 void Model::SetBlobReturn(bool val)
1125 {
1126  vis.blob_return = val;
1127 }
1128 
1129 void Model::SetRangerReturn(double val)
1130 {
1131  vis.ranger_return = val;
1132 }
1133 
1134 void Model::SetBoundary(bool val)
1135 {
1136  boundary = val;
1137 }
1138 
1139 void Model::SetGuiNose(bool val)
1140 {
1141  gui.nose = val;
1142 }
1143 
1144 void Model::SetGuiMove(bool val)
1145 {
1146  gui.move = val;
1147 }
1148 
1149 void Model::SetGuiGrid(bool val)
1150 {
1151  gui.grid = val;
1152 }
1153 
1154 void Model::SetGuiOutline(bool val)
1155 {
1156  gui.outline = val;
1157 }
1158 
1160 {
1161  watts = val;
1162 }
1163 
1165 {
1166  map_resolution = val;
1167 }
1168 
1169 // set the pose of model in global coordinates
1170 void Model::SetGlobalPose(const Pose &gpose)
1171 {
1172  SetPose(parent ? parent->GlobalToLocal(gpose) : gpose);
1173 }
1174 
1175 int Model::SetParent(Model *newparent)
1176 {
1177  Pose oldPose = GetGlobalPose();
1178 
1179  // remove the model from its old parent (if it has one)
1180  if (parent)
1181  parent->RemoveChild(this);
1182  else
1183  world->RemoveChild(this);
1184  // link from the model to its new parent
1185  this->parent = newparent;
1186 
1187  if (newparent)
1188  newparent->AddChild(this);
1189  else
1190  world->AddModel(this);
1191 
1193 
1194  SetGlobalPose(oldPose); // Needs to recalculate position due to change in parent
1195 
1196  return 0; // ok
1197 }
1198 
1199 // get the model's position in the global frame
1201 {
1202  // if I'm a top level model, my global pose is my local pose
1203  if (parent == NULL)
1204  return pose;
1205 
1206  // otherwise
1207  Pose global_pose = parent->GetGlobalPose() + pose;
1208 
1209  if (parent->stack_children) // should we be on top of our parent?
1210  global_pose.z += parent->geom.size.z;
1211 
1212  return global_pose;
1213 }
1214 
1215 // set the model's pose in the local frame
1216 void Model::SetPose(const Pose &newpose)
1217 {
1218  // if the pose has changed, we need to do some work
1219  if (pose != newpose) {
1220  pose = newpose;
1221  pose.a = normalize(pose.a);
1222 
1223  // if( isnan( pose.a ) )
1224  // printf( "SetPose bad angle %s [%.2f %.2f %.2f %.2f]\n",
1225  // token, pose.x, pose.y, pose.z, pose.a
1226  // );
1227 
1228  NeedRedraw();
1229 
1230  UnMapWithChildren(0);
1231  UnMapWithChildren(1);
1232 
1233  MapWithChildren(0);
1234  MapWithChildren(1);
1235 
1236  world->dirty = true;
1237  }
1238 
1240 }
1241 
1243 {
1244  assert(wf);
1245  assert(wf_entity);
1246 
1247  PRINT_DEBUG1("Model \"%s\" loading...", token.c_str());
1248 
1249  // choose the thread to run in, if thread_safe > 0
1250  event_queue_num = wf->ReadInt(wf_entity, "event_queue", event_queue_num);
1251 
1252  if (wf->PropertyExists(wf_entity, "joules")) {
1253  if (!power_pack)
1254  power_pack = new PowerPack(this);
1255 
1256  joules_t j = wf->ReadFloat(wf_entity, "joules", power_pack->GetStored());
1257 
1258  /* assume that the store is full, so the capacity is the same as
1259  the charge */
1260  power_pack->SetStored(j);
1261  power_pack->SetCapacity(j);
1262  }
1263 
1264  if (wf->PropertyExists(wf_entity, "joules_capacity")) {
1265  if (!power_pack)
1266  power_pack = new PowerPack(this);
1267 
1268  power_pack->SetCapacity(wf->ReadFloat(wf_entity, "joules_capacity", power_pack->GetCapacity()));
1269  }
1270 
1271  if (wf->PropertyExists(wf_entity, "kjoules")) {
1272  if (!power_pack)
1273  power_pack = new PowerPack(this);
1274 
1275  joules_t j = 1000.0 * wf->ReadFloat(wf_entity, "kjoules", power_pack->GetStored());
1276 
1277  /* assume that the store is full, so the capacity is the same as
1278  the charge */
1279  power_pack->SetStored(j);
1280  power_pack->SetCapacity(j);
1281  }
1282 
1283  if (wf->PropertyExists(wf_entity, "kjoules_capacity")) {
1284  if (!power_pack)
1285  power_pack = new PowerPack(this);
1286 
1288  1000.0 * wf->ReadFloat(wf_entity, "kjoules_capacity", power_pack->GetCapacity()));
1289  }
1290 
1291  watts = wf->ReadFloat(wf_entity, "watts", watts);
1292  watts_give = wf->ReadFloat(wf_entity, "give_watts", watts_give);
1293  watts_take = wf->ReadFloat(wf_entity, "take_watts", watts_take);
1294 
1295  debug = wf->ReadInt(wf_entity, "debug", debug);
1296 
1297  const std::string &name = wf->ReadString(wf_entity, "name", token);
1298  if (name != token)
1299  SetToken(name);
1300 
1301  // PRINT_WARN1( "%s::Load", token );
1302 
1303  Geom g(GetGeom());
1304 
1305  if (wf->PropertyExists(wf_entity, "origin"))
1306  g.pose.Load(wf, wf_entity, "origin");
1307 
1308  if (wf->PropertyExists(wf_entity, "size"))
1309  g.size.Load(wf, wf_entity, "size");
1310 
1311  SetGeom(g);
1312 
1313  if (wf->PropertyExists(wf_entity, "pose"))
1314  SetPose(GetPose().Load(wf, wf_entity, "pose"));
1315 
1316  if (wf->PropertyExists(wf_entity, "color")) {
1317  Color col(1, 0, 0); // red;
1318  const std::string &colorstr = wf->ReadString(wf_entity, "color", "");
1319  if (colorstr != "") {
1320  if (colorstr == "random")
1321  col = Color(drand48(), drand48(), drand48());
1322  else
1323  col = Color(colorstr);
1324  }
1325  this->SetColor(col);
1326  }
1327 
1328  this->SetColor(GetColor().Load(wf, wf_entity));
1329 
1330  if (wf->ReadInt(wf_entity, "noblocks", 0)) {
1331  if (has_default_block) {
1332  blockgroup.Clear();
1333  has_default_block = false;
1334  blockgroup.CalcSize();
1335  }
1336  }
1337 
1338  if (wf->PropertyExists(wf_entity, "bitmap")) {
1339  const std::string bitmapfile = wf->ReadString(wf_entity, "bitmap", "");
1340  if (bitmapfile == "")
1341  PRINT_WARN1("model %s specified empty bitmap filename\n", Token());
1342 
1343  if (has_default_block) {
1344  blockgroup.Clear();
1345  has_default_block = false;
1346  }
1347 
1348  blockgroup.LoadBitmap(bitmapfile, wf);
1349  }
1350 
1351  if (wf->PropertyExists(wf_entity, "boundary")) {
1352  this->SetBoundary(wf->ReadInt(wf_entity, "boundary", this->boundary));
1353 
1354  if (boundary) {
1355  // PRINT_WARN1( "setting boundary for %s\n", token );
1356 
1357  blockgroup.CalcSize();
1358 
1359  const double epsilon = 0.01;
1360  const bounds3d_t b = blockgroup.BoundingBox();
1361 
1362  const Size size(b.x.max - b.x.min, b.y.max - b.y.min, b.z.max - b.z.min);
1363 
1364  //static size_t count=0;
1365  //printf( "boundaries %lu\n", ++count );
1366  AddBlockRect(b.x.min, b.y.min, epsilon, size.y, size.z);
1367  AddBlockRect(b.x.min, b.y.min, size.x, epsilon, size.z);
1368  AddBlockRect(b.x.min, b.y.max - epsilon, size.x, epsilon, size.z);
1369  AddBlockRect(b.x.max - epsilon, b.y.min, epsilon, size.y, size.z);
1370  }
1371  }
1372 
1373  this->stack_children = wf->ReadInt(wf_entity, "stack_children", this->stack_children);
1374 
1375  kg_t m = wf->ReadFloat(wf_entity, "mass", this->mass);
1376  if (m != this->mass)
1377  SetMass(m);
1378 
1379  vis.Load(wf, wf_entity);
1380  SetFiducialReturn(vis.fiducial_return); // may have some work to do
1381 
1382  gui.Load(wf, wf_entity);
1383 
1384  double res = wf->ReadFloat(wf_entity, "map_resolution", this->map_resolution);
1385  if (res != this->map_resolution)
1386  SetMapResolution(res);
1387 
1388  if (wf->PropertyExists(wf_entity, "friction")) {
1389  this->SetFriction(wf->ReadFloat(wf_entity, "friction", this->friction));
1390  }
1391 
1392  if (CProperty *ctrlp = wf->GetProperty(wf_entity, "ctrl")) {
1393  for (unsigned int index = 0; index < ctrlp->values.size(); index++) {
1394  const char *lib = wf->GetPropertyValue(ctrlp, index);
1395 
1396  if (!lib)
1397  printf("Error - NULL library name specified for model %s\n", Token());
1398  else
1399  LoadControllerModule(lib);
1400  }
1401  }
1402 
1403  // internally interval is in usec, but we use msec in worldfiles
1404  interval = 1000 * wf->ReadInt(wf_entity, "update_interval", interval / 1000);
1405 
1406  Say(wf->ReadString(wf_entity, "say", ""));
1407 
1408  int trail_length = wf->ReadInt(wf_entity, "trail_length", (int)trail.size() );
1409  trail.resize(trail_length);
1410  trail_interval = wf->ReadInt(wf_entity, "trail_interval", trail_interval);
1411 
1412  this->alwayson = wf->ReadInt(wf_entity, "alwayson", alwayson);
1413  if (alwayson)
1414  Subscribe();
1415 
1416  // call any type-specific load callbacks
1417  this->CallCallbacks(CB_LOAD);
1418 
1419  // we may well have changed blocks or geometry
1420  blockgroup.CalcSize();
1421 
1422  // remove and re-add to both layers
1423  UnMapWithChildren(0);
1424  MapWithChildren(0);
1425 
1426  UnMapWithChildren(1);
1427  MapWithChildren(1);
1428 
1429  if (this->debug)
1430  printf("Model \"%s\" is in debug mode\n", Token());
1431 
1432  PRINT_DEBUG1("Model \"%s\" loading complete", Token());
1433 }
1434 
1435 void Model::Save(void)
1436 {
1437  // printf( "Model \"%s\" saving...\n", Token() );
1438 
1439  // some models were not loaded, so have no worldfile. Just bail here.
1440  if (wf == NULL)
1441  return;
1442 
1443  assert(wf_entity);
1444 
1445  PRINT_DEBUG5("saving model %s pose [ %.2f, %.2f, %.2f, %.2f]", token.c_str(), pose.x, pose.y,
1446  pose.z, pose.a);
1447 
1448  // just in case
1449  pose.a = normalize(pose.a);
1450  geom.pose.a = normalize(geom.pose.a);
1451 
1452  if (wf->PropertyExists(wf_entity, "pose"))
1453  pose.Save(wf, wf_entity, "pose");
1454 
1455  if (wf->PropertyExists(wf_entity, "size"))
1456  geom.size.Save(wf, wf_entity, "size");
1457 
1458  if (wf->PropertyExists(wf_entity, "origin"))
1459  geom.pose.Save(wf, wf_entity, "origin");
1460 
1461  vis.Save(wf, wf_entity);
1462 
1463  // call any type-specific save callbacks
1465 
1466  PRINT_DEBUG1("Model \"%s\" saving complete.", token.c_str());
1467 }
1468 
1469 void Model::LoadControllerModule(const char *lib)
1470 {
1471  // printf( "[Ctrl \"%s\"", lib );
1472  // fflush(stdout);
1473 
1474  /* Initialise libltdl. */
1475  int errors = lt_dlinit();
1476  if (errors) {
1477  printf("Libtool error: %s. Failed to init libtool. Quitting\n",
1478  lt_dlerror()); // report the error from libtool
1479  puts("libtool error #1");
1480  fflush(stdout);
1481  exit(-1);
1482  }
1483 
1484  lt_dlsetsearchpath(FileManager::stagePath().c_str());
1485 
1486  // printf( "STAGEPATH: %s\n", FileManager::stagePath().c_str());
1487  // printf( "ltdl search path: %s\n", lt_dlgetsearchpath() );
1488 
1489  // PLUGIN_PATH now defined in config.h
1490  lt_dladdsearchdir(PLUGIN_PATH);
1491 
1492  // printf( "ltdl search path: %s\n", lt_dlgetsearchpath() );
1493 
1494  lt_dlhandle handle = NULL;
1495 
1496  // the library name is the first word in the string
1497  char libname[256];
1498  sscanf(lib, "%255s %*s", libname);
1499 
1500  if ((handle = lt_dlopenext(libname))) {
1501 // printf( "]" );
1502 // Refer to:
1503 // http://stackoverflow.com/questions/14543801/iso-c-forbids-casting-between-pointer-to-function-and-pointer-to-object
1504 #ifdef __GNUC__
1505  __extension__
1506 #endif
1507  model_callback_t initfunc = (model_callback_t)lt_dlsym(handle, "Init");
1508  if (initfunc == NULL) {
1509  printf("(Libtool error: %s.) Something is wrong with your plugin.\n",
1510  lt_dlerror()); // report the error from libtool
1511  puts("libtool error #1");
1512  fflush(stdout);
1513  exit(-1);
1514  }
1515 
1516  AddCallback(CB_INIT, initfunc,
1517  new CtrlArgs(lib,
1518  World::ctrlargs)); // pass complete string into initfunc
1519  } else {
1520  printf("(Libtool error: %s.) Can't open your plugin.\n",
1521  lt_dlerror()); // report the error from libtool
1522 
1523  PRINT_ERR1("Failed to open \"%s\". Check that it can be found by searching "
1524  "the directories in your STAGEPATH environment variable, or the "
1525  "current directory if STAGEPATH is not set.]\n",
1526  libname);
1527 
1528  printf("ctrl \"%s\" STAGEPATH \"%s\"\n", libname, PLUGIN_PATH);
1529 
1530  puts("libtool error #2");
1531  fflush(stdout);
1532  exit(-1);
1533  }
1534 
1535  fflush(stdout);
1536 }
void SetBoundary(bool val)
Definition: model.cc:1134
virtual void PushColor(Color col)
Definition: stage.hh:2059
Model class
Definition: stage.hh:1651
meters_t ModelHeight() const
Definition: model.cc:617
int subs
the number of subscriptions to this model
Definition: stage.hh:1846
void Save(Worldfile *wf, int section, const char *keyword) const
Definition: model.cc:170
void LoadBlock(Worldfile *wf, int entity)
Definition: model.cc:368
void Enqueue(unsigned int queue_num, usec_t delay, Model *mod, model_callback_t cb, void *arg)
Definition: stage.hh:1005
Bounds y
volume extent along y axis, initially zero
Definition: stage.hh:429
static const double DEFAULT_FRICTION
Definition: model.cc:151
void UnMapWithChildren(unsigned int layer)
Definition: model.cc:502
Flag * Nibble(double portion)
Definition: model.cc:998
int CallCallbacks(callback_type_t type)
double a
Definition: stage.hh:216
meters_t cellheight
Definition: stage.hh:1821
float res
Definition: make_rsn.c:27
bool stack_children
whether child models should be stacked on top of this model or not
Definition: stage.hh:1843
Model * GetUnusedModelOfType(const std::string &type)
Definition: model.cc:770
double max
largest value in range, initially zero
Definition: stage.hh:412
World class
Definition: stage.hh:764
Pose GetGlobalPose() const
Definition: model.cc:1200
PowerPack * FindPowerPack() const
Definition: model.cc:833
void Save(Worldfile *wf, int section, const char *keyword)
Definition: model.cc:182
void AppendTouchingModels(std::set< Model *> &touchers)
Definition: blockgroup.cc:35
The Stage library uses its own namespace.
Definition: canvas.hh:8
void EnableEnergy(Model *m)
Definition: stage.hh:1012
void CallUpdateCallbacks(void)
Definition: model.cc:612
joules_t GetCapacity() const
Definition: powerpack.cc:212
void SetPose(const Pose &pose)
Definition: model.cc:1216
must be the last entry: counts the number of types
Definition: stage.hh:1743
#define PRINT_DEBUG5(m, a, b, c, d, e)
Definition: stage.hh:649
bounds3d_t BoundingBox() const
Definition: blockgroup.cc:53
meters_t x
Definition: stage.hh:243
void Save(Worldfile *wf, int wf_entity)
Definition: model.cc:205
void RegisterOption(Option *opt)
Register an Option for pickup by the GUI.
Definition: world.cc:1115
Model * TestCollision()
Definition: model.cc:661
Color GetColor()
Definition: stage.hh:1719
kg_t GetMassOfChildren() const
Definition: model.cc:803
void SetGlobalPose(const Pose &gpose)
Definition: model.cc:1170
PowerPack * power_pack
Definition: stage.hh:1810
const std::string ReadString(int entity, const char *name, const std::string &value)
Definition: worldfile.cc:1450
virtual void AddChild(Model *mod)
Definition: ancestor.cc:15
meters_t cellwidth
Definition: stage.hh:1821
std::string token
Definition: stage.hh:671
virtual void UpdateCharge()
Definition: model.cc:676
CProperty * GetProperty(int entity, const char *name)
Definition: worldfile.cc:1375
const char * GetPropertyValue(CProperty *property, int index)
Definition: worldfile.cc:1421
Pose GetPose() const
Definition: stage.hh:2250
void AddToPose(const Pose &pose)
Definition: model.cc:638
void SetStall(bool stall)
Definition: model.cc:1092
Geom geom
Definition: stage.hh:1777
bool RandomPoseInFreeSpace(meters_t xmin, meters_t xmax, meters_t ymin, meters_t ymax, size_t max_iter=0)
Definition: model.cc:644
bool IsDescendent(const Model *testmod) const
Definition: model.cc:428
bool used
TRUE iff this model has been returned by GetUnusedModelOfType()
Definition: stage.hh:1887
const std::string type
Definition: stage.hh:1883
watts_t watts
power consumed by this model
Definition: stage.hh:1889
int ReadTuple(const int entity, const char *name, const unsigned int first, const unsigned int num, const char *format,...)
Definition: worldfile.cc:1572
int(* model_callback_t)(Model *mod, void *user)
Definition: stage.hh:540
void EraseAll(T thing, C &cont)
Definition: stage.hh:584
std::vector< point_t > pts
Definition: stage.hh:1822
double min
smallest value in range, initially zero
Definition: stage.hh:410
Size & Load(Worldfile *wf, int section, const char *keyword)
Definition: model.cc:164
Size size
extent
Definition: stage.hh:379
uint32_t id
Definition: stage.hh:1794
void Rasterize(uint8_t *data, unsigned int width, unsigned int height, meters_t cellwidth, meters_t cellheight)
Definition: model.cc:849
void AddFlag(Flag *flag)
Definition: model.cc:323
#define PRINT_DEBUG2(m, a, b)
Definition: stage.hh:646
double ppm
the resolution of the world model in pixels per meter
Definition: stage.hh:828
meters_t map_resolution
Definition: stage.hh:1799
Pose & Load(Worldfile *wf, int section, const char *keyword)
Definition: model.cc:175
std::vector< point_int_t > LocalToPixels(const std::vector< point_t > &local) const
Definition: model.cc:469
void SetColor(const Color &col)
Definition: model.cc:1011
Flag(const Color &color, double size)
Definition: model.cc:994
watts_t watts_take
Definition: stage.hh:1897
void SetGuiGrid(bool val)
Definition: model.cc:1149
unsigned int event_queue_num
Definition: stage.hh:1886
usec_t interval_energy
time between updates of powerpack in usec
Definition: stage.hh:1796
void AddBlockRect(meters_t x, meters_t y, meters_t dx, meters_t dy, meters_t dz)
Definition: model.cc:378
virtual void PopColor()
Definition: stage.hh:2061
void RemoveFlag(Flag *flag)
Definition: model.cc:331
virtual void RemoveChild(Model *mod)
Definition: ancestor.cc:28
std::vector< TrailItem > trail
Definition: stage.hh:1866
double ranger_return
0 - 1
Definition: stage.hh:1931
void Dissipate(joules_t j)
Definition: powerpack.cc:234
kg_t mass
Definition: stage.hh:1800
void SetMapResolution(meters_t res)
Definition: model.cc:1164
void Say(const std::string &str)
Definition: model.cc:410
void LoadControllerModule(const char *lib)
Definition: model.cc:1469
bool thread_safe
Definition: stage.hh:1851
meters_t z
location in 3 axes
Definition: stage.hh:259
meters_t y
Definition: stage.hh:259
Worldfile * wf
Definition: stage.hh:1899
void WriteInt(int entity, const char *name, int value)
Definition: worldfile.cc:1480
void WriteTuple(const int entity, const char *name, const unsigned int first, const unsigned int count, const char *format,...)
Definition: worldfile.cc:1635
void MapFromRoot(unsigned int layer)
Find the root model, and map/unmap the whole tree.
Definition: model.cc:497
bool disabled
Definition: stage.hh:1763
double watts_t
Definition: stage.hh:212
Geom GetGeom() const
Definition: stage.hh:2247
Pose LocalToGlobal(const Pose &pose) const
Definition: stage.hh:2296
int total_subs
the total number of subscriptions to all models
Definition: stage.hh:838
void pose_inverse_shift(const Pose &pose)
Definition: gl.cc:18
double normalize(double a)
Definition: stage.hh:163
int wf_entity
Definition: stage.hh:1900
Model * Root()
Definition: stage.hh:2190
std::list< Visualizer * > cv_list
Definition: stage.hh:1766
#define PRINT_DEBUG3(m, a, b, c)
Definition: stage.hh:647
WorldGui * world_gui
Pointer to the GUI world - NULL if running in non-gui mode.
Definition: stage.hh:1902
void RegisterOption(Option *opt)
Definition: model.cc:844
usec_t sim_time
the current sim time in this world in microseconds
Definition: stage.hh:853
GuiState & Load(Worldfile *wf, int wf_entity)
Definition: model.cc:219
void ChargeStart()
Definition: stage.hh:1641
friend class Block
Definition: stage.hh:1657
Flag * PopFlag()
Definition: model.cc:347
void AddCallback(callback_type_t type, model_callback_t cb, void *user)
virtual void AddModel(Model *mod)
Definition: world.cc:264
double r
Definition: stage.hh:216
bool PropertyExists(int section, const char *token)
Definition: worldfile.cc:1401
void FiducialErase(Model *mod)
Definition: stage.hh:824
static Pose Random(meters_t xmin, meters_t xmax, meters_t ymin, meters_t ymax)
Definition: stage.hh:269
void SetData(uint8_t *data, unsigned int width, unsigned int height, meters_t cellwidth, meters_t cellheight)
Definition: model.cc:968
virtual void Print(char *prefix) const
Definition: model.cc:542
void AppendTouchingModels(std::set< Model *> &touchers)
Definition: model.cc:656
virtual void Visualize(Model *mod, Camera *cam)
Definition: model.cc:885
Model * GetUnsubscribedModelOfType(const std::string &type) const
Definition: model.cc:739
void Draw(GLUquadric *quadric)
Definition: model.cc:1033
static std::string stagePath()
Return the STAGEPATH environment variable.
Definition: file_manager.cc:31
Pose pose
position
Definition: stage.hh:378
void PushFlag(Flag *flag)
Definition: model.cc:339
void LoadBitmap(const std::string &bitmapfile, Worldfile *wf)
Definition: blockgroup.cc:294
bool dirty
iff true, a gui redraw would be required
Definition: stage.hh:785
meters_t y
Definition: stage.hh:446
void FiducialInsert(Model *mod)
Definition: stage.hh:817
uint64_t usec_t
Definition: stage.hh:203
double meters_t
Definition: stage.hh:191
meters_t x
Definition: stage.hh:446
usec_t interval
time between updates in usec
Definition: stage.hh:1795
meters_t y
Definition: stage.hh:243
void WriteFloat(int entity, const char *name, double value)
Definition: worldfile.cc:1489
std::list< Flag * > flag_list
Definition: stage.hh:1769
virtual void Save()
Definition: model.cc:1435
static int UpdateWrapper(Model *mod, void *)
Definition: stage.hh:2017
bool IsRelated(const Model *testmod) const
Definition: model.cc:441
unsigned int GetEventQueue(Model *mod) const
Definition: world.cc:678
int SetParent(Model *newparent)
Definition: model.cc:1175
void SetBlobReturn(bool val)
Definition: model.cc:1124
bool IsAntecedent(const Model *testmod) const
Definition: model.cc:416
unsigned int width
Definition: stage.hh:1820
friend class PowerPack
Definition: stage.hh:1660
void AddVisualizer(Visualizer *custom_visual, bool on_by_default)
Definition: model_draw.cc:242
void Redraw()
Definition: model.cc:765
meters_t z
Definition: stage.hh:243
virtual void Startup()
Definition: model.cc:566
watts_t watts_give
Definition: stage.hh:1893
double b
Definition: stage.hh:216
virtual void SetToken(const std::string &str)
Definition: stage.hh:1905
void Subscribe()
Definition: model.cc:516
void SetRangerReturn(double val)
Definition: model.cc:1129
void SetFriction(double friction)
Definition: model.cc:857
void AddPoint(meters_t x, meters_t y)
Definition: model.cc:984
bool has_default_block
Definition: stage.hh:1791
void draw_string(float x, float y, float z, const char *string)
Definition: gl.cc:61
void SetSize(double sz)
Definition: model.cc:1022
static uint32_t count
Definition: stage.hh:1666
bool stall
Set to true iff the model collided with something else.
Definition: stage.hh:1845
void SetFiducialReturn(int fid)
Definition: model.cc:1102
void Map(unsigned int layer)
Definition: blockgroup.cc:114
virtual void Update()
Definition: model.cc:593
double g
Definition: stage.hh:216
void SetGripperReturn(bool val)
Definition: model.cc:1097
void NeedRedraw()
Definition: model.cc:755
virtual ~Model()
Definition: model.cc:300
Bounds x
volume extent along x axis, intially zero
Definition: stage.hh:427
void TransferTo(PowerPack *dest, joules_t amount)
Definition: powerpack.cc:177
void LoadBlock(Worldfile *wf, int entity)
Definition: blockgroup.cc:288
unsigned int height
Definition: stage.hh:1820
void Map()
Definition: stage.hh:1976
void NeedRedraw()
Definition: stage.hh:890
unsigned int trail_index
Definition: stage.hh:1869
void Unsubscribe()
Definition: model.cc:529
bool alwayson
Definition: stage.hh:1677
void Rasterize(uint8_t *data, unsigned int width, unsigned int height, meters_t cellwidth, meters_t cellheight)
Definition: blockgroup.cc:332
std::vector< std::set< cb_t > > callbacks
Definition: stage.hh:1750
bool mapped
Definition: stage.hh:1670
virtual void Load()
Definition: model.cc:1242
class Stg::Model::Visibility vis
virtual void RemoveModel(Model *mod)
Definition: world.cc:275
uint64_t trail_interval
Definition: stage.hh:1877
void UnMapFromRoot(unsigned int layer)
Definition: model.cc:511
BlockGroup blockgroup
Definition: stage.hh:1679
#define PRINT_DEBUG1(m, a)
Definition: stage.hh:645
Bounds z
volume extent along z axis, initially zero
Definition: stage.hh:431
Stg::Model::RasterVis rastervis
Pose pose
Definition: stage.hh:1807
double ReadFloat(int entity, const char *name, double value)
Definition: worldfile.cc:1503
static std::map< std::string, creator_t > name_map
Definition: stage.hh:2320
bool debug
Definition: stage.hh:666
void InitControllers()
Definition: model.cc:318
void SetWatts(watts_t watts)
Definition: model.cc:1159
void SetGuiMove(bool val)
Definition: model.cc:1144
static std::map< id_t, Model * > modelsbyid
Definition: stage.hh:1667
World * world
Pointer to the world in which this model exists.
Definition: stage.hh:1901
bool rebuild_displaylist
iff true, regenerate block display list before redraw
Definition: stage.hh:1840
bool data_fresh
Definition: stage.hh:1758
std::string say_string
if non-empty, this string is displayed in the GUI
Definition: stage.hh:1841
std::vector< std::queue< Model * > > pending_update_callbacks
Definition: stage.hh:992
#define PRINT_ERR1(m, a)
Definition: stage.hh:591
void SetCapacity(joules_t j)
Definition: powerpack.cc:199
void UnMap(unsigned int layer)
Definition: blockgroup.cc:123
double Constrain(double value)
returns value, but no smaller than min and no larger than max.
Definition: model.cc:159
kg_t GetTotalMass() const
Definition: model.cc:793
Pose GlobalToLocal(const Pose &pose) const
Definition: model.cc:398
void SetFiducialKey(int key)
Definition: model.cc:1114
std::list< PowerPack * > pps_charging
Definition: stage.hh:1814
void UnMap()
Definition: stage.hh:1985
void SetStored(joules_t j)
Definition: powerpack.cc:227
void SetGuiNose(bool val)
Definition: model.cc:1139
std::vector< Model * > children
Definition: stage.hh:664
void MapWithChildren(unsigned int layer)
Definition: model.cc:488
double constrain(double val, double minval, double maxval)
return val, or minval if val < minval, or maxval if val > maxval
Definition: stage.cc:236
int ReadInt(int entity, const char *name, int value)
Definition: worldfile.cc:1470
void SetGeom(const Geom &src)
Definition: model.cc:1061
Model * GetChild(const std::string &name) const
Definition: model.cc:862
Bounds & Load(Worldfile *wf, int section, const char *keyword)
Definition: model.cc:153
virtual void Shutdown()
Definition: model.cc:582
#define FOR_EACH(I, C)
Definition: stage.hh:580
class Stg::Model::GuiState gui
radians_t a
rotation about the z axis.
Definition: stage.hh:260
std::map< std::string, unsigned int > child_type_counts
Definition: stage.hh:662
void DisableEnergy(Model *m)
Definition: stage.hh:1013
double friction
Definition: stage.hh:1773
Model * TestCollision()
Definition: blockgroup.cc:41
void SetMass(kg_t mass)
Definition: model.cc:1087
double kg_t
Definition: stage.hh:206
Color color
Definition: stage.hh:1753
Model * GetModel(const std::string &name) const
Definition: world.cc:688
int boundary
Definition: stage.hh:1683
bool log_state
iff true, model state is logged
Definition: stage.hh:1798
static std::string ctrlargs
Definition: stage.hh:776
virtual void Redraw(void)
Definition: stage.hh:872
double joules_t
Definition: stage.hh:209
virtual const char * PrintWithPose() const
Definition: model.cc:555
std::vector< Option * > drawOptions
Definition: stage.hh:1672
#define PRINT_WARN1(m, a)
Definition: stage.hh:604
joules_t GetStored() const
Definition: powerpack.cc:217
void SetGuiOutline(bool val)
Definition: model.cc:1154
Visibility & Load(Worldfile *wf, int wf_entity)
Definition: model.cc:193
void BecomeParentOf(Model *child)
Definition: model.cc:819
void AppendBlock(const Block &block)
Definition: blockgroup.cc:22
Property class.
Definition: worldfile.hh:39
void UpdateTrail()
Definition: model.cc:725
void SetColor(Color col)
Definition: model.cc:1081
meters_t x
Definition: stage.hh:259
const char * Token() const
Definition: stage.hh:689
void ClearBlocks()
Definition: model.cc:360
void SetObstacleReturn(bool val)
Definition: model.cc:1119
Model * parent
Definition: stage.hh:1803
usec_t last_update
time of last update in us
Definition: stage.hh:1797


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