space.cpp
Go to the documentation of this file.
1 
11 #include <argos3/core/utility/string_utilities.h>
12 #include <argos3/core/utility/math/range.h>
13 #include <argos3/core/utility/logging/argos_log.h>
14 #include <argos3/core/utility/math/rng.h>
15 #include <argos3/core/simulator/simulator.h>
16 #include <argos3/core/simulator/entity/composable_entity.h>
17 #include <argos3/core/simulator/entity/positional_entity.h>
18 #include <argos3/core/simulator/loop_functions.h>
19 #include <cstring>
20 #include "space.h"
21 
22 namespace argos {
23 
24  /****************************************/
25  /****************************************/
26 
28  m_cSimulator(CSimulator::GetInstance()),
29  m_unSimulationClock(0),
30  m_pcFloorEntity(nullptr),
31  m_ptPhysicsEngines(nullptr),
32  m_ptMedia(nullptr) {}
33 
34  /****************************************/
35  /****************************************/
36 
38  /* Get reference to physics engine and media vectors */
41  /* Get the arena center and size */
43  GetNodeAttribute(t_tree, "size", m_cArenaSize);
45  m_cArenaCenter + m_cArenaSize / 2.0f);
46  /*
47  * Add and initialize all entities in XML
48  */
49  /* Start from the entities placed manually */
50  TConfigurationNodeIterator itArenaItem;
51  for(itArenaItem = itArenaItem.begin(&t_tree);
52  itArenaItem != itArenaItem.end();
53  ++itArenaItem) {
54  if(itArenaItem->Value() != "distribute") {
55  CEntity* pcEntity = CFactory<CEntity>::New(itArenaItem->Value());
56  pcEntity->Init(*itArenaItem);
57  CallEntityOperation<CSpaceOperationAddEntity, CSpace, void>(*this, *pcEntity);
58  }
59  }
60  /* Place the entities to distribute automatically */
61  for(itArenaItem = itArenaItem.begin(&t_tree);
62  itArenaItem != itArenaItem.end();
63  ++itArenaItem) {
64  if(itArenaItem->Value() == "distribute") {
65  Distribute(*itArenaItem);
66  }
67  }
68  }
69 
70  /****************************************/
71  /****************************************/
72 
73  void CSpace::Reset() {
74  /* Reset the simulation clock */
76  /* Reset the entities */
77  for(UInt32 i = 0; i < m_vecEntities.size(); ++i) {
78  m_vecEntities[i]->Reset();
79  }
80  }
81 
82  /****************************************/
83  /****************************************/
84 
85  void CSpace::Destroy() {
86  /* Remove all entities */
87  while(!m_vecRootEntities.empty()) {
88  CallEntityOperation<CSpaceOperationRemoveEntity, CSpace, void>(*this, *m_vecRootEntities.back());
89  }
90  }
91 
92  /****************************************/
93  /****************************************/
94 
96  const std::string& str_pattern) {
97  for(auto it = m_vecEntities.begin();
98  it != m_vecEntities.end(); ++it) {
99  if(MatchPattern((*it)->GetId(), str_pattern)) {
100  t_buffer.push_back(*it);
101  }
102  }
103  }
104 
105  /****************************************/
106  /****************************************/
107 
108  CSpace::TMapPerType& CSpace::GetEntitiesByTypeImpl(const std::string& str_type) const {
109  auto itEntities = m_mapEntitiesPerTypePerId.find(str_type);
110  if(itEntities != m_mapEntitiesPerTypePerId.end()){
111  return const_cast<CSpace::TMapPerType&>(itEntities->second);
112  } else {
113  THROW_ARGOSEXCEPTION("Entity map for type \"" << str_type << "\" not found.");
114  }
115  }
116  /****************************************/
117  /****************************************/
118 
119  void CSpace::Update() {
120  /* Increase the simulation clock */
122  /* Perform the 'act' phase for controllable entities */
124  /* Update the physics engines */
125  UpdatePhysics();
126  /* Update media */
127  UpdateMedia();
128  /* Call loop functions */
130  /*
131  * If the loop functions did not use ARGoS threads during PreStep(), tell
132  * the waiting thread pool to continue.
133  */
136  }
137  /*
138  * Reset callback to NULL to disable entity iteration for PostStep()
139  * unless enabled again by the loop functions.
140  */
141  m_cbControllableEntityIter = nullptr;
142  /* Perform the 'sense+step' phase for controllable entities */
144  /* Call loop functions */
146 
147  /*
148  * If the loop functions did not use ARGoS threads during PostStep(), tell
149  * the waiting thread pool to continue.
150  */
153  }
154  /*
155  * Reset callback to NULL to disable entity iteration for next PreStep()
156  * unless enabled again by the loop functions.
157  */
158  m_cbControllableEntityIter = nullptr;
159  /* Flush logs */
160  LOG.Flush();
161  LOGERR.Flush();
162  }
163 
164  /****************************************/
165  /****************************************/
166 
168  m_vecControllableEntities.push_back(&c_entity);
169  }
170 
171  /****************************************/
172  /****************************************/
173 
175  auto it = find(m_vecControllableEntities.begin(),
177  &c_entity);
178  if(it != m_vecControllableEntities.end()) {
179  m_vecControllableEntities.erase(it);
180  }
181  }
182 
183  /****************************************/
184  /****************************************/
185 
187  /* Get a reference to the root entity */
188  CEntity* pcToAdd = &c_entity.GetRootEntity();
189  /* Get a reference to the position of the entity */
190  const CVector3& cPos = c_entity.GetOriginAnchor().Position;
191  /* Go through engines and check which ones could house the entity */
192  CPhysicsEngine::TVector vecPotentialEngines;
193  for(size_t i = 0; i < m_ptPhysicsEngines->size(); ++i) {
194  if((*m_ptPhysicsEngines)[i]->IsPointContained(cPos)) {
195  vecPotentialEngines.push_back((*m_ptPhysicsEngines)[i]);
196  }
197  }
198  /* If no engine can house the entity, bomb out */
199  if(vecPotentialEngines.empty()) {
200  THROW_ARGOSEXCEPTION("No physics engines available to house entity \"" << pcToAdd->GetId() << "\"@(" << cPos << ").");
201  }
202  /* If the entity is not movable, add the entity to all the matching engines */
203  if(! c_entity.IsMovable()) {
204  bool bAdded = false;
205  for(size_t i = 0; i < vecPotentialEngines.size(); ++i) {
206  bAdded |= vecPotentialEngines[i]->AddEntity(*pcToAdd);
207  }
208  if(!bAdded) {
209  std::ostringstream ossMsg;
210  ossMsg << "None of the matching physics engines (";
211  ossMsg << "\"" << vecPotentialEngines[0]->GetId() << "\"";
212  for(size_t i = 1; i < vecPotentialEngines.size(); ++i) {
213  ossMsg << ",\"" << vecPotentialEngines[i]->GetId() << "\"";
214  }
215  ossMsg << ") can house non-movable entity \"" << pcToAdd->GetId() << "\"@(" << cPos << ").";
216  THROW_ARGOSEXCEPTION(ossMsg.str());
217  }
218  }
219  /* If the entity is movable, only one engine can be associated to the embodied entity */
220  else if(vecPotentialEngines.size() == 1) {
221  /* Only one engine matches, bingo! */
222  if(!vecPotentialEngines[0]->AddEntity(*pcToAdd)) {
223  THROW_ARGOSEXCEPTION("The matching physics engine (\"" << vecPotentialEngines[0]->GetId() << "\"), cannot house movable entity \"" << pcToAdd->GetId() << "\"@(" << cPos << ").");
224  }
225  }
226  else {
227  /* More than one engine matches, pick the first that can manage the entity */
228  for(size_t i = 0; i < vecPotentialEngines.size(); ++i) {
229  if(vecPotentialEngines[i]->AddEntity(*pcToAdd)) return;
230  }
231  /* No engine can house the entity */
232  std::ostringstream ossMsg;
233  ossMsg << "None of the matching physics engines (";
234  ossMsg << "\"" << vecPotentialEngines[0]->GetId() << "\"";
235  for(size_t i = 1; i < vecPotentialEngines.size(); ++i) {
236  ossMsg << ",\"" << vecPotentialEngines[i]->GetId() << "\"";
237  }
238  ossMsg << ") can house movable entity \"" << pcToAdd->GetId() << "\"@(" << cPos << ").";
239  THROW_ARGOSEXCEPTION(ossMsg.str());
240  }
241  }
242 
243  /****************************************/
244  /****************************************/
245 
247  public:
248  virtual ~RealNumberGenerator() {}
249  virtual CVector3 operator()(bool b_is_retry) = 0;
250  };
251 
253  public:
254  ConstantGenerator(const CVector3& c_value) :
255  m_cValue(c_value) {}
256 
257  inline virtual CVector3 operator()(bool b_is_retry) {
258  return m_cValue;
259  }
260  private:
261  CVector3 m_cValue;
262 
263  };
264 
266  public:
268  const CVector3& c_max) :
269  m_cMin(c_min),
270  m_cMax(c_max) {}
271  inline virtual CVector3 operator()(bool b_is_retry) {
272  Real fRandX =
273  m_cMax.GetX() > m_cMin.GetX() ?
274  CSimulator::GetInstance().GetRNG()->Uniform(CRange<Real>(m_cMin.GetX(), m_cMax.GetX())) :
275  m_cMax.GetX();
276  Real fRandY =
277  m_cMax.GetY() > m_cMin.GetY() ?
278  CSimulator::GetInstance().GetRNG()->Uniform(CRange<Real>(m_cMin.GetY(), m_cMax.GetY())) :
279  m_cMax.GetY();
280  Real fRandZ =
281  m_cMax.GetZ() > m_cMin.GetZ() ?
282  CSimulator::GetInstance().GetRNG()->Uniform(CRange<Real>(m_cMin.GetZ(), m_cMax.GetZ())) :
283  m_cMax.GetZ();
284  return CVector3(fRandX, fRandY, fRandZ);
285  }
286  private:
287  CVector3 m_cMin;
288  CVector3 m_cMax;
289  };
290 
292  public:
294  const CVector3& c_std_dev) :
295  m_cMean(c_mean),
296  m_cStdDev(c_std_dev) {}
297  inline virtual CVector3 operator()(bool b_is_retry) {
298  return CVector3(CSimulator::GetInstance().GetRNG()->Gaussian(m_cStdDev.GetX(), m_cMean.GetX()),
299  CSimulator::GetInstance().GetRNG()->Gaussian(m_cStdDev.GetY(), m_cMean.GetY()),
300  CSimulator::GetInstance().GetRNG()->Gaussian(m_cStdDev.GetZ(), m_cMean.GetZ()));
301  }
302  private:
303  CVector3 m_cMean;
304  CVector3 m_cStdDev;
305  };
306 
308  public:
309  GridGenerator(const CVector3 c_center,
310  const UInt32 un_layout[],
311  const CVector3 c_distances):
312  m_cCenter(c_center),
313  m_cDistances(c_distances),
314  m_unNumEntityPlaced(0) {
315  m_unLayout[0] = un_layout[0];
316  m_unLayout[1] = un_layout[1];
317  m_unLayout[2] = un_layout[2];
318  /* Check if layout is sane */
319  if( m_unLayout[0] == 0 || m_unLayout[1] == 0 || m_unLayout[2] == 0 ) {
320  THROW_ARGOSEXCEPTION("'layout' values (distribute position, method 'grid') must all be different than 0");
321  }
322  }
323 
324  virtual CVector3 operator()(bool b_is_retry) {
325  if(b_is_retry) {
326  THROW_ARGOSEXCEPTION("Impossible to place entity #" << m_unNumEntityPlaced << " in grid");
327  }
328  CVector3 cReturn;
329  if(m_unNumEntityPlaced < m_unLayout[0] * m_unLayout[1] * m_unLayout[2]) {
330  cReturn.SetX(m_cCenter.GetX() + ( m_unLayout[0] - 1 ) * m_cDistances.GetX() * 0.5 - ( m_unNumEntityPlaced % m_unLayout[0] ) * m_cDistances.GetX());
331  cReturn.SetY(m_cCenter.GetY() + ( m_unLayout[1] - 1 ) * m_cDistances.GetY() * 0.5 - ( m_unNumEntityPlaced / m_unLayout[0] ) % m_unLayout[1] * m_cDistances.GetY());
332  cReturn.SetZ(m_cCenter.GetZ() + ( m_unLayout[2] - 1 ) * m_cDistances.GetZ() * 0.5 - ( m_unNumEntityPlaced / ( m_unLayout[0] * m_unLayout[1] ) ) * m_cDistances.GetZ());
333  ++m_unNumEntityPlaced;
334  }
335  else {
336  THROW_ARGOSEXCEPTION("Distribute position, method 'grid': trying to place more entities than allowed "
337  "by the 'layout', check your 'quantity' tag");
338  }
339  return cReturn;
340  }
341 
342  private:
343  CVector3 m_cCenter;
344  UInt32 m_unLayout[3];
345  CVector3 m_cDistances;
346  UInt32 m_unNumEntityPlaced;
347  };
348 
349  /****************************************/
350  /****************************************/
351 
353  std::string strMethod;
354  GetNodeAttribute(t_tree, "method", strMethod);
355  if(strMethod == "uniform") {
356  CVector3 cMin, cMax;
357  GetNodeAttribute(t_tree, "min", cMin);
358  GetNodeAttribute(t_tree, "max", cMax);
359  if(! (cMin <= cMax)) {
360  THROW_ARGOSEXCEPTION("Uniform generator: the min is not less than or equal to max: " << cMin << " / " << cMax);
361  }
362  return new UniformGenerator(cMin, cMax);
363  }
364  else if(strMethod == "gaussian") {
365  CVector3 cMean, cStdDev;
366  GetNodeAttribute(t_tree, "mean", cMean);
367  GetNodeAttribute(t_tree, "std_dev", cStdDev);
368  return new GaussianGenerator(cMean, cStdDev);
369  }
370  else if(strMethod == "constant") {
371  CVector3 cValues;
372  GetNodeAttribute(t_tree, "values", cValues);
373  return new ConstantGenerator(cValues);
374  }
375  else if(strMethod == "grid") {
376  CVector3 cCenter,cDistances;
377  GetNodeAttribute(t_tree, "center", cCenter);
378  GetNodeAttribute(t_tree, "distances", cDistances);
379  UInt32 unLayout[3];
380  std::string strLayout;
381  GetNodeAttribute(t_tree, "layout", strLayout);
382  ParseValues<UInt32> (strLayout, 3, unLayout, ',');
383  return new GridGenerator(cCenter, unLayout, cDistances);
384  }
385  else {
386  THROW_ARGOSEXCEPTION("Unknown distribution method \"" << strMethod << "\"");
387  }
388  }
389 
390  /****************************************/
391  /****************************************/
392 
393  static CEmbodiedEntity* GetEmbodiedEntity(CEntity* pc_entity) {
394  /* Is the entity embodied itself? */
395  auto* pcEmbodiedTest = dynamic_cast<CEmbodiedEntity*>(pc_entity);
396  if(pcEmbodiedTest != nullptr) {
397  return pcEmbodiedTest;
398  }
399  /* Is the entity composable with an embodied component? */
400  auto* pcComposableTest = dynamic_cast<CComposableEntity*>(pc_entity);
401  if(pcComposableTest != nullptr) {
402  if(pcComposableTest->HasComponent("body")) {
403  return &(pcComposableTest->GetComponent<CEmbodiedEntity>("body"));
404  }
405  }
406  /* No embodied entity found */
407  return nullptr;
408  }
409 
410  /****************************************/
411  /****************************************/
412 
413  static CPositionalEntity* GetPositionalEntity(CEntity* pc_entity) {
414  /* Is the entity positional itself? */
415  auto* pcPositionalTest = dynamic_cast<CPositionalEntity*>(pc_entity);
416  if(pcPositionalTest != nullptr) {
417  return pcPositionalTest;
418  }
419  /* Is the entity composable with a positional component? */
420  auto* pcComposableTest = dynamic_cast<CComposableEntity*>(pc_entity);
421  if(pcComposableTest != nullptr) {
422  if(pcComposableTest->HasComponent("position")) {
423  return &(pcComposableTest->GetComponent<CPositionalEntity>("position"));
424  }
425  }
426  /* No positional entity found */
427  return nullptr;
428  }
429 
430  /****************************************/
431  /****************************************/
432 
434  try {
435  /* Get the needed nodes */
436  TConfigurationNode cPositionNode;
437  cPositionNode = GetNode(t_tree, "position");
438  TConfigurationNode cOrientationNode;
439  cOrientationNode = GetNode(t_tree, "orientation");
440  TConfigurationNode cEntityNode;
441  cEntityNode = GetNode(t_tree, "entity");
442  /* Create the real number generators */
443  RealNumberGenerator* pcPositionGenerator = CreateGenerator(cPositionNode);
444  RealNumberGenerator* pcOrientationGenerator = CreateGenerator(cOrientationNode);
445  /* How many entities? */
446  UInt32 unQuantity;
447  GetNodeAttribute(cEntityNode, "quantity", unQuantity);
448  /* How many trials before failing? */
449  UInt32 unMaxTrials;
450  GetNodeAttribute(cEntityNode, "max_trials", unMaxTrials);
451  /* Get the (optional) entity base numbering */
452  UInt64 unBaseNum = 0;
453  GetNodeAttributeOrDefault(cEntityNode, "base_num", unBaseNum, unBaseNum);
454  /* Get the entity type to add (take only the first, ignore additional if any) */
456  itEntity = itEntity.begin(&cEntityNode);
457  if(itEntity == itEntity.end()) {
458  THROW_ARGOSEXCEPTION("No entity to distribute specified.");
459  }
460  /* Get the entity base ID */
461  std::string strBaseId;
462  GetNodeAttribute(*itEntity, "id", strBaseId);
463  /* Add the requested entities */
464  for(UInt32 i = 0; i < unQuantity; ++i) {
465  /* Copy the entity XML tree */
466  TConfigurationNode& tEntityTree = *itEntity;
467  /* Set progressive ID */
468  SetNodeAttribute(tEntityTree, "id", strBaseId + ToString(i+unBaseNum));
469  /* Go on until the entity is placed with no collisions or
470  the max number of trials has been exceeded */
471  UInt32 unTrials = 0;
472  bool bDone = false;
473  bool bRetry = false;
474  CEntity* pcEntity;
475  do {
476  /* Create entity */
477  pcEntity = CFactory<CEntity>::New(tEntityTree.Value());
478  /*
479  * Now that you have the entity, check whether the
480  * entity is positional or embodied or has one such
481  * component.
482  *
483  * In case the entity is positional but not embodied,
484  * there's no need to check for collisions.
485  *
486  * In case the entity is embodied, we must check for
487  * collisions.
488  *
489  * To check for collisions, we add the entity in the
490  * place where it's supposed to be, then we ask the
491  * engine if that entity is colliding with something.
492  *
493  * In case of collision, we remove the entity and try a
494  * different position/orientation.
495  */
496  /* Check whether the entity is positional */
497  CPositionalEntity* pcPositionalEntity = GetPositionalEntity(pcEntity);
498  if(pcPositionalEntity != nullptr) {
499  /* Set the position */
500  SetNodeAttribute(tEntityTree, "position", (*pcPositionGenerator)(bRetry));
501  /* Set the orientation */
502  SetNodeAttribute(tEntityTree, "orientation", (*pcOrientationGenerator)(bRetry));
503  /* Init the entity (this also creates the components, if pcEntity is a composable) */
504  pcEntity->Init(tEntityTree);
505  /* Wherever we want to put the entity, it's OK, add it */
506  CallEntityOperation<CSpaceOperationAddEntity, CSpace, void>(*this, *pcEntity);
507  bDone = true;
508  }
509  else {
510  /* Assume the entity is embodied */
511  /* If the tree does not have a 'body' node, create a new one */
512  if(!NodeExists(tEntityTree, "body")) {
513  TConfigurationNode tBodyNode("body");
514  AddChildNode(tEntityTree, tBodyNode);
515  }
516  /* Get 'body' node */
517  TConfigurationNode& tBodyNode = GetNode(tEntityTree, "body");
518  /* Set the position */
519  SetNodeAttribute(tBodyNode, "position", (*pcPositionGenerator)(bRetry));
520  /* Set the orientation */
521  SetNodeAttribute(tBodyNode, "orientation", (*pcOrientationGenerator)(bRetry));
522  /* Init the entity (this also creates the components, if pcEntity is a composable) */
523  pcEntity->Init(tEntityTree);
524  /* Check whether the entity is indeed embodied */
525  CEmbodiedEntity* pcEmbodiedEntity = GetEmbodiedEntity(pcEntity);
526  if(pcEmbodiedEntity != nullptr) {
527  /* Yes, the entity is embodied */
528  /* Add it to the space and to the designated physics engine */
529  CallEntityOperation<CSpaceOperationAddEntity, CSpace, void>(*this, *pcEntity);
530  /* Check if it's colliding with anything else */
531  if(pcEmbodiedEntity->IsCollidingWithSomething()) {
532  /* Set retry to true */
533  bRetry = true;
534  /* Get rid of the entity */
535  CallEntityOperation<CSpaceOperationRemoveEntity, CSpace, void>(*this, *pcEntity);
536  /* Increase the trial count */
537  ++unTrials;
538  /* Too many trials? */
539  if(unTrials > unMaxTrials) {
540  /* Yes, bomb out */
541  THROW_ARGOSEXCEPTION("Exceeded max trials when trying to distribute objects of type " <<
542  tEntityTree.Value() << " with base id \"" <<
543  strBaseId << "\". I managed to place only " << i << " objects.");
544  }
545  /* Retry with a new position */
546  }
547  else {
548  /* No collision, we're done with this entity */
549  bDone = true;
550  }
551  }
552  else {
553  THROW_ARGOSEXCEPTION("Cannot distribute entities that are not positional nor embodied, and \"" << tEntityTree.Value() << "\" is neither.");
554  }
555  }
556  }
557  while(!bDone);
558  }
559  /* Delete the generators, now unneeded */
560  delete pcPositionGenerator;
561  delete pcOrientationGenerator;
562  }
563  catch(CARGoSException& ex) {
564  THROW_ARGOSEXCEPTION_NESTED("Error while trying to distribute entities", ex);
565  }
566  }
567 
568  /****************************************/
569  /****************************************/
570 
571 }
#define THROW_ARGOSEXCEPTION_NESTED(message, nested)
This macro throws an ARGoS exception with the passed message and nesting the passed exception.
#define THROW_ARGOSEXCEPTION(message)
This macro throws an ARGoS exception with the passed message.
unsigned int UInt32
32-bit unsigned integer.
Definition: datatypes.h:97
unsigned long long UInt64
64-bit unsigned integer.
Definition: datatypes.h:107
float Real
Collects all ARGoS code.
Definition: datatypes.h:39
The namespace containing all the ARGoS related code.
Definition: ci_actuator.h:12
void SetNodeAttribute(TConfigurationNode &t_node, const std::string &str_attribute, const T &t_value)
Sets the value of the wanted node's attribute.
ticpp::Iterator< ticpp::Element > TConfigurationNodeIterator
The iterator for the ARGoS configuration XML node.
CARGoSLog LOGERR(std::cerr, SLogColor(ARGOS_LOG_ATTRIBUTE_BRIGHT, ARGOS_LOG_COLOR_RED))
Definition: argos_log.h:180
bool MatchPattern(const std::string &str_input, const std::string &str_pattern)
Returns true if str_pattern is matched by str_input.
TConfigurationNode & GetNode(TConfigurationNode &t_node, const std::string &str_tag)
Given a tree root node, returns the first of its child nodes with the wanted name.
void GetNodeAttributeOrDefault(TConfigurationNode &t_node, const std::string &str_attribute, T &t_buffer, const T &t_default)
Returns the value of a node's attribute, or the passed default value.
ticpp::Element TConfigurationNode
The ARGoS configuration XML node.
CARGoSLog LOG(std::cout, SLogColor(ARGOS_LOG_ATTRIBUTE_BRIGHT, ARGOS_LOG_COLOR_GREEN))
Definition: argos_log.h:179
bool NodeExists(TConfigurationNode &t_node, const std::string &str_tag)
Given a tree root node, returns true if one of its child nodes has the wanted name.
void AddChildNode(TConfigurationNode &t_parent_node, TConfigurationNode &t_child_node)
Adds an XML node as child of another XML node.
std::string ToString(const T &t_value)
Converts the given parameter to a std::string.
RealNumberGenerator * CreateGenerator(TConfigurationNode &t_tree)
Definition: space.cpp:352
void GetNodeAttribute(TConfigurationNode &t_node, const std::string &str_attribute, T &t_buffer)
Returns the value of a node's attribute.
An entity that contains a pointer to the user-defined controller.
This entity is a link to a body in the physics engine.
bool IsMovable() const
Returns true if the entity is movable.
virtual bool IsCollidingWithSomething() const
Returns true if this entity is colliding with another object.
const SAnchor & GetOriginAnchor() const
Returns a const reference to the origin anchor associated to this entity.
The basic entity type.
Definition: entity.h:90
std::vector< CEntity * > TVector
A vector of entities.
Definition: entity.h:97
const std::string & GetId() const
Returns the id of this entity.
Definition: entity.h:157
CEntity & GetRootEntity()
Returns the root entity containing this entity.
Definition: entity.cpp:115
virtual void Init(TConfigurationNode &t_tree)
Initializes the state of the entity from the XML configuration tree.
Definition: entity.cpp:40
virtual void PostStep()
Executes user-defined logic right after a control step is executed.
virtual void PreStep()
Executes user-defined logic right before a control step is executed.
std::vector< CPhysicsEngine * > TVector
CVector3 Position
The position of the anchor wrt the global coordinate system.
Definition: physics_model.h:51
The core class of ARGOS.
Definition: simulator.h:62
CRandom::CRNG * GetRNG()
Returns the random generator of the "argos" category.
Definition: simulator.h:210
CLoopFunctions & GetLoopFunctions()
Returns a reference to the loop functions associated to the current experiment.
Definition: simulator.h:236
static CSimulator & GetInstance()
Returns the instance to the CSimulator class.
Definition: simulator.cpp:78
CMedium::TVector & GetMedia()
Returns the list of currently existing media.
Definition: simulator.h:149
CPhysicsEngine::TVector & GetPhysicsEngines()
Returns the list of currently existing physics engines.
Definition: simulator.h:119
virtual ~RealNumberGenerator()
Definition: space.cpp:248
virtual CVector3 operator()(bool b_is_retry)=0
ConstantGenerator(const CVector3 &c_value)
Definition: space.cpp:254
virtual CVector3 operator()(bool b_is_retry)
Definition: space.cpp:257
virtual CVector3 operator()(bool b_is_retry)
Definition: space.cpp:271
UniformGenerator(const CVector3 &c_min, const CVector3 &c_max)
Definition: space.cpp:267
virtual CVector3 operator()(bool b_is_retry)
Definition: space.cpp:297
GaussianGenerator(const CVector3 &c_mean, const CVector3 &c_std_dev)
Definition: space.cpp:293
GridGenerator(const CVector3 c_center, const UInt32 un_layout[], const CVector3 c_distances)
Definition: space.cpp:309
virtual CVector3 operator()(bool b_is_retry)
Definition: space.cpp:324
void Distribute(TConfigurationNode &t_tree)
Definition: space.cpp:433
CControllableEntity::TVector m_vecControllableEntities
A vector of controllable entities.
Definition: space.h:491
virtual void Init(TConfigurationNode &t_tree)
Initializes the space using the <arena> section of the XML configuration file.
Definition: space.cpp:37
virtual void Destroy()
Destroys the space and all its entities.
Definition: space.cpp:85
virtual void Reset()
Reset the space and all its entities.
Definition: space.cpp:73
bool ControllableEntityIterationEnabled() const
Definition: space.h:449
CRange< CVector3 > m_cArenaLimits
Arena limits.
Definition: space.h:474
virtual void UpdatePhysics()=0
virtual void Update()
Updates the space.
Definition: space.cpp:119
CSpace()
Class constructor.
Definition: space.cpp:27
CPhysicsEngine::TVector * m_ptPhysicsEngines
A pointer to the list of physics engines.
Definition: space.h:497
UInt32 m_unSimulationClock
The current simulation clock.
Definition: space.h:465
void GetEntitiesMatching(CEntity::TVector &t_buffer, const std::string &str_pattern)
Returns the entities matching a given pattern.
Definition: space.cpp:95
TControllableEntityIterCBType m_cbControllableEntityIter
Callback for iterating over entities from within the loop functions.
Definition: space.h:503
TMapPerTypePerId m_mapEntitiesPerTypePerId
A map of maps of all the simulated entities.
Definition: space.h:488
CMedium::TVector * m_ptMedia
A pointer to the list of media.
Definition: space.h:500
virtual void ControllableEntityIterationWaitAbort()
If the loop functions do not perform entity iteration in either of the PreStep() or PostStep() functi...
Definition: space.h:443
virtual void UpdateControllableEntitiesAct()=0
void AddEntity(ENTITY &c_entity)
Adds an entity of the given type.
Definition: space.h:274
void IncreaseSimulationClock(UInt32 un_increase=1)
Increases the simulation clock by the wanted value.
Definition: space.h:363
CVector3 m_cArenaSize
Arena size.
Definition: space.h:471
CVector3 m_cArenaCenter
Arena center.
Definition: space.h:468
CEntity::TVector m_vecRootEntities
A vector of all the entities without a parent.
Definition: space.h:480
std::map< std::string, CAny, std::less< std::string > > TMapPerType
A map of entities indexed by type description.
Definition: space.h:56
virtual void UpdateMedia()=0
virtual void AddEntityToPhysicsEngine(CEmbodiedEntity &c_entity)
Definition: space.cpp:186
virtual void AddControllableEntity(CControllableEntity &c_entity)
Definition: space.cpp:167
CSimulator & m_cSimulator
Definition: space.h:462
CEntity::TVector m_vecEntities
A vector of entities.
Definition: space.h:477
virtual void UpdateControllableEntitiesSenseStep()=0
virtual void RemoveControllableEntity(CControllableEntity &c_entity)
Definition: space.cpp:174
The exception that wraps all errors in ARGoS.
Real Gaussian(Real f_std_dev, Real f_mean=0.0f)
Returns a random value from a Gaussian distribution.
Definition: rng.cpp:152
CRadians Uniform(const CRange< CRadians > &c_range)
Returns a random value from a uniform distribution.
Definition: rng.cpp:87
A 3D vector class.
Definition: vector3.h:31
void SetY(const Real f_y)
Sets the y coordinate of this vector.
Definition: vector3.h:129
Real GetX() const
Returns the x coordinate of this vector.
Definition: vector3.h:105
void SetX(const Real f_x)
Sets the x coordinate of this vector.
Definition: vector3.h:113
void SetZ(const Real f_z)
Sets the z coordinate of this vector.
Definition: vector3.h:145
Real GetY() const
Returns the y coordinate of this vector.
Definition: vector3.h:121
Real GetZ() const
Returns the z coordinate of this vector.
Definition: vector3.h:137
static TYPE * New(const std::string &str_label)
Creates a new object of type TYPE
Definition: factory_impl.h:48