embodied_entity.cpp
Go to the documentation of this file.
1 
7 #include "embodied_entity.h"
8 #include "composable_entity.h"
9 #include <argos3/core/simulator/space/space.h>
10 #include <argos3/core/simulator/simulator.h>
11 #include <argos3/core/utility/string_utilities.h>
12 #include <argos3/core/utility/math/matrix/rotationmatrix3.h>
13 
14 namespace argos {
15 
16  /****************************************/
17  /****************************************/
18 
20  CEntity(pc_parent),
21  m_bMovable(true),
22  m_sBoundingBox(NULL),
23  m_psOriginAnchor(NULL) {}
24 
25  /****************************************/
26  /****************************************/
27 
29  const std::string& str_id,
30  const CVector3& c_position,
31  const CQuaternion& c_orientation,
32  bool b_movable) :
33  CEntity(pc_parent, str_id),
34  m_bMovable(b_movable),
35  m_sBoundingBox(NULL),
36  m_psOriginAnchor(new SAnchor(*this,
37  "origin",
38  0,
39  CVector3(),
40  CQuaternion(),
41  c_position,
42  c_orientation)),
43  m_cInitOriginPosition(c_position),
44  m_cInitOriginOrientation(c_orientation) {
45  /* Add anchor to map and enable it */
47  EnableAnchor("origin");
48  }
49 
50  /****************************************/
51  /****************************************/
52 
54  if(!m_bMovable && m_sBoundingBox != NULL) {
55  delete m_sBoundingBox;
56  }
57  for(std::map<std::string, SAnchor*>::iterator it = m_mapAnchors.begin();
58  it != m_mapAnchors.end(); ++it) {
59  /* it->second points to the current anchor */
60  delete it->second;
61  }
62  m_mapAnchors.clear();
63  }
64 
65  /****************************************/
66  /****************************************/
67 
69  try {
70  /* Initialize base entity */
71  CEntity::Init(t_tree);
72  /* Get the position of the entity */
74  /* Get the orientation of the entity */
76  /* Create origin anchor */
77  m_psOriginAnchor = new SAnchor(*this,
78  "origin",
79  0,
80  CVector3(),
81  CQuaternion(),
84  /* Add anchor to map and enable it */
86  EnableAnchor("origin");
87  /* Embodied entities are movable by default */
88  m_bMovable = true;
89  }
90  catch(CARGoSException& ex) {
91  THROW_ARGOSEXCEPTION_NESTED("Failed to initialize embodied entity \"" << GetContext() << GetId() << "\".", ex);
92  }
93  }
94 
95  /****************************************/
96  /****************************************/
97 
99  /* Reset origin anchor first */
102  /* Reset other anchors */
103  SAnchor* psAnchor;
104  for(std::map<std::string, SAnchor*>::iterator it = m_mapAnchors.begin();
105  it != m_mapAnchors.end(); ++it) {
106  /* it->second points to the current anchor */
107  psAnchor = it->second;
108  if(psAnchor->Index > 0) {
109  /* Calculate global position and orientation */
110  psAnchor->Position = psAnchor->OffsetPosition;
112  psAnchor->Position += m_cInitOriginPosition;
114  }
115  }
116  }
117 
118  /****************************************/
119  /****************************************/
120 
121  SAnchor& CEmbodiedEntity::AddAnchor(const std::string& str_id,
122  const CVector3& c_offset_position,
123  const CQuaternion& c_offset_orientation) {
124  /* Make sure the anchor id is unique */
125  if(m_mapAnchors.count(str_id) > 0 ) {
126  THROW_ARGOSEXCEPTION("Embodied entity \"" << GetContext() + GetId() << "\" already has an anchor with id " << str_id);
127  }
128  /* Calculate anchor position */
129  CVector3 cPos = c_offset_position;
131  cPos += m_psOriginAnchor->Position;
132  /* Calculate anchor orientation */
133  CQuaternion cOrient = m_psOriginAnchor->Orientation * c_offset_orientation;
134  /* Create anchor */
135  SAnchor* psAnchor = new SAnchor(*this,
136  str_id,
137  m_mapAnchors.size(),
138  c_offset_position,
139  c_offset_orientation,
140  cPos,
141  cOrient);
142  /* Add anchor to map */
143  m_mapAnchors[str_id] = psAnchor;
144  return *psAnchor;
145  }
146 
147  /****************************************/
148  /****************************************/
149 
150  void CEmbodiedEntity::EnableAnchor(const std::string& str_id) {
151  /* Lookup the anchor id */
152  std::map<std::string, SAnchor*>::iterator it = m_mapAnchors.find(str_id);
153  /* Found? */
154  if(it == m_mapAnchors.end()) {
155  THROW_ARGOSEXCEPTION("Embodied entity \"" << GetContext() + GetId() << "\" has no anchor with id " << str_id);
156  }
157  /* Now it->second points to the requested anchor */
158  /* Increase the in-use count */
159  ++(it->second->InUseCount);
160  /* Add to vector of enabled anchors if necessary */
161  if(it->second->InUseCount == 1) {
162  m_vecEnabledAnchors.push_back(it->second);
163  }
164  }
165 
166  /****************************************/
167  /****************************************/
168 
169  void CEmbodiedEntity::DisableAnchor(const std::string& str_id) {
170  /* Cannot disable the origin anchor */
171  if(str_id == "origin") return;
172  /* Lookup the anchor id */
173  std::vector<SAnchor*>::iterator it = std::find(m_vecEnabledAnchors.begin(),
174  m_vecEnabledAnchors.end(),
175  str_id);
176  /* Found? */
177  if(it == m_vecEnabledAnchors.end()) return;
178  /* Now *it points to the requested anchor */
179  /* Decrease the in-use count */
180  --((*it)->InUseCount);
181  /* Remove from vector of enabled anchors if necessary */
182  if((*it)->InUseCount == 0) {
183  m_vecEnabledAnchors.erase(it);
184  }
185  }
186 
187  /****************************************/
188  /****************************************/
189 
190  const SAnchor& CEmbodiedEntity::GetAnchor(const std::string& str_id) const {
191  /* Lookup the anchor id */
192  std::map<std::string, SAnchor*>::const_iterator it = m_mapAnchors.find(str_id);
193  /* Found? */
194  if(it == m_mapAnchors.end()) {
195  THROW_ARGOSEXCEPTION("Embodied entity \"" << GetContext() + GetId() << "\" has no anchor with id " << str_id);
196  }
197  /* Now it->second points to the requested anchor */
198  return *(it->second);
199  }
200 
201  /****************************************/
202  /****************************************/
203 
204  SAnchor& CEmbodiedEntity::GetAnchor(const std::string& str_id) {
205  /* Lookup the anchor id */
206  std::map<std::string, SAnchor*>::iterator it = m_mapAnchors.find(str_id);
207  /* Found? */
208  if(it == m_mapAnchors.end()) {
209  THROW_ARGOSEXCEPTION("Embodied entity \"" << GetContext() + GetId() << "\" has no anchor with id " << str_id);
210  }
211  /* Now it->second points to the requested anchor */
212  return *(it->second);
213  }
214 
215  /****************************************/
216  /****************************************/
217 
218  bool CEmbodiedEntity::IsAnchorEnabled(const std::string& str_id) {
219  /* Lookup the anchor id */
220  std::map<std::string, SAnchor*>::const_iterator it = m_mapAnchors.find(str_id);
221  /* Found? */
222  if(it == m_mapAnchors.end()) {
223  THROW_ARGOSEXCEPTION("Embodied entity \"" << GetContext() + GetId() << "\" has no anchor with id " << str_id);
224  }
225  /* Now it->second points to the requested anchor */
226  return (it->second->InUseCount > 0);
227  }
228 
229  /****************************************/
230  /****************************************/
231 
233  if(GetPhysicsModelsNum() == 0) {
234  /* No engine associated to this entity */
235  THROW_ARGOSEXCEPTION("CEmbodiedEntity::GetBoundingBox() : entity \"" << GetContext() << GetId() << "\" is not associated to any engine");
236  }
237  return *m_sBoundingBox;
238  }
239 
240  /****************************************/
241  /****************************************/
242 
244  return m_tPhysicsModelVector.size();
245  }
246 
247  /****************************************/
248  /****************************************/
249 
250  void CEmbodiedEntity::AddPhysicsModel(const std::string& str_engine_id,
251  CPhysicsModel& c_physics_model) {
252  if(m_bMovable && GetPhysicsModelsNum() > 0) {
253  THROW_ARGOSEXCEPTION(GetContext() << GetId() << " is a movable embodied entity and can't have more than 1 physics engine entity associated");
254  }
255  m_tPhysicsModelMap[str_engine_id] = &c_physics_model;
256  m_tPhysicsModelVector.push_back(&c_physics_model);
258  }
259 
260  /****************************************/
261  /****************************************/
262 
263  void CEmbodiedEntity::RemovePhysicsModel(const std::string& str_engine_id) {
264  CPhysicsModel::TMap::iterator itMap = m_tPhysicsModelMap.find(str_engine_id);
265  if(itMap == m_tPhysicsModelMap.end()) {
266  THROW_ARGOSEXCEPTION("Entity \"" << GetContext() << GetId() << "\" has no associated entity in physics engine " << str_engine_id);
267  }
268  CPhysicsModel::TVector::iterator itVec = std::find(m_tPhysicsModelVector.begin(),
269  m_tPhysicsModelVector.end(),
270  itMap->second);
271  m_tPhysicsModelMap.erase(itMap);
272  m_tPhysicsModelVector.erase(itVec);
274  }
275 
276  /****************************************/
277  /****************************************/
278 
279  const CPhysicsModel& CEmbodiedEntity::GetPhysicsModel(size_t un_idx) const {
280  if(un_idx > m_tPhysicsModelVector.size()) {
281  THROW_ARGOSEXCEPTION("CEmbodiedEntity::GetPhysicsModel: entity \"" << GetContext() << GetId() << "\": the passed index " << un_idx << " is out of bounds, the max allowed is " << m_tPhysicsModelVector.size());
282  }
283  return *m_tPhysicsModelVector[un_idx];
284  }
285 
286  /****************************************/
287  /****************************************/
288 
290  if(un_idx > m_tPhysicsModelVector.size()) {
291  THROW_ARGOSEXCEPTION("CEmbodiedEntity::GetPhysicsModel: entity \"" << GetContext() << GetId() << "\": the passed index " << un_idx << " is out of bounds, the max allowed is " << m_tPhysicsModelVector.size());
292  }
293  return *m_tPhysicsModelVector[un_idx];
294  }
295 
296  /****************************************/
297  /****************************************/
298 
299  const CPhysicsModel& CEmbodiedEntity::GetPhysicsModel(const std::string& str_engine_id) const {
300  CPhysicsModel::TMap::const_iterator it = m_tPhysicsModelMap.find(str_engine_id);
301  if(it == m_tPhysicsModelMap.end()) {
302  THROW_ARGOSEXCEPTION("Entity \"" << GetContext() << GetId() << "\" has no associated entity in physics engine \"" << str_engine_id << "\"");
303  }
304  return *(it->second);
305  }
306 
307  /****************************************/
308  /****************************************/
309 
310  CPhysicsModel& CEmbodiedEntity::GetPhysicsModel(const std::string& str_engine_id) {
311  CPhysicsModel::TMap::iterator it = m_tPhysicsModelMap.find(str_engine_id);
312  if(it == m_tPhysicsModelMap.end()) {
313  THROW_ARGOSEXCEPTION("Entity \"" << GetContext() << GetId() << "\" has no associated entity in physics engine \"" << str_engine_id << "\"");
314  }
315  return *(it->second);
316  }
317 
318  /****************************************/
319  /****************************************/
320 
321  bool CEmbodiedEntity::MoveTo(const CVector3& c_position,
322  const CQuaternion& c_orientation,
323  bool b_check_only) {
324  /* Can't move an entity with no model associated */
325  if(GetPhysicsModelsNum() == 0) return false;
326  /* Save current position and orientation */
327  CVector3 cOriginalPosition = m_psOriginAnchor->Position;
328  CQuaternion cOriginalOrientation = m_psOriginAnchor->Orientation;
329  /* Treat specially the case of movable entity */
330  if(m_bMovable) {
331  /* Move entity and check for collisions */
332  m_tPhysicsModelVector[0]->MoveTo(c_position, c_orientation);
333  bool bNoCollision = ! m_tPhysicsModelVector[0]->IsCollidingWithSomething();
334  /* Depending on the presence of collisions... */
335  if(bNoCollision && !b_check_only) {
336  /* No collision and not a simple check */
337  /* Tell the caller that we managed to move the entity */
338  return true;
339  }
340  else {
341  /* Collision or just a check, undo changes */
342  m_tPhysicsModelVector[0]->MoveTo(cOriginalPosition, cOriginalOrientation);
343  /* Tell the caller about collisions */
344  return bNoCollision;
345  }
346  }
347  else {
348  /* The entity is not movable, go through all the models */
349  size_t i;
350  bool bNoCollision = true;
351  for(i = 0; i < m_tPhysicsModelVector.size() && bNoCollision; ++i) {
352  m_tPhysicsModelVector[i]->MoveTo(c_position, c_orientation);
353  bNoCollision = !m_tPhysicsModelVector[i]->IsCollidingWithSomething();
354  }
355  if(bNoCollision && !b_check_only) {
356  /* No collision and not a simple check */
358  /* Tell the caller that we managed to move the entity */
359  return true;
360  }
361  else {
362  /* No collision or just a check, undo changes */
363  for(size_t j = 0; j < i; ++j) {
364  m_tPhysicsModelVector[j]->MoveTo(cOriginalPosition, cOriginalOrientation);
365  }
366  /* Tell the caller about collisions */
367  return bNoCollision;
368  }
369  }
370  }
371 
372  /****************************************/
373  /****************************************/
374 
375 #define CHECK_CORNER(MINMAX, COORD, OP) \
376  if(m_sBoundingBox->MINMAX ## Corner.Get ## COORD() OP sBBox.MINMAX ## Corner.Get ## COORD()) { \
377  m_sBoundingBox->MINMAX ## Corner.Set ## COORD(sBBox.MINMAX ## Corner.Get ## COORD()); \
378  }
379 
381  if(GetPhysicsModelsNum() > 0) {
382  /*
383  * There is at least one physics engine entity associated
384  */
385  if(m_bMovable) {
386  /* The bounding box points directly to the associated model bounding box */
387  m_sBoundingBox = &m_tPhysicsModelVector[0]->GetBoundingBox();
388  }
389  else {
390  /* The bounding box is obtained taking the extrema of all the bboxes of all the engines */
391  if(m_sBoundingBox == NULL) {
393  }
394  *m_sBoundingBox = m_tPhysicsModelVector[0]->GetBoundingBox();
395  for(size_t i = 1; i < GetPhysicsModelsNum(); ++i) {
396  const SBoundingBox& sBBox = m_tPhysicsModelVector[0]->GetBoundingBox();
397  CHECK_CORNER(Min, X, >);
398  CHECK_CORNER(Min, Y, >);
399  CHECK_CORNER(Min, Z, >);
400  CHECK_CORNER(Max, X, <);
401  CHECK_CORNER(Max, Y, <);
402  CHECK_CORNER(Max, Z, <);
403  }
404  }
405  }
406  else {
407  /*
408  * No physics engine entity associated
409  */
410  if(! m_bMovable && m_sBoundingBox != NULL) {
411  /* A non-movable entity has its own bounding box, delete it */
412  delete m_sBoundingBox;
413  }
414  m_sBoundingBox = NULL;
415  }
416  }
417 
418  /****************************************/
419  /****************************************/
420 
422  /* If no model is associated, you can't call this function */
423  if(m_tPhysicsModelVector.empty()) {
424  THROW_ARGOSEXCEPTION("CEmbodiedEntity::IsCollidingWithSomething() called on entity \"" <<
425  GetContext() << GetId() <<
426  "\", but this entity has not been added to any physics engine.");
427  }
428  /* Special case: if there is only one model, check that directly */
429  if(m_tPhysicsModelVector.size() == 1) {
430  return m_tPhysicsModelVector[0]->IsCollidingWithSomething();
431  }
432  /* Multiple associations, go through them */
433  else {
434  /* Return true at the first detected collision */
435  for(size_t i = 0; i < m_tPhysicsModelVector.size(); ++i) {
437  return true;
438  }
439  }
440  /* If you get here it's because there are collisions */
441  return false;
442  }
443  }
444 
445  /****************************************/
446  /****************************************/
447 
448  bool operator==(const SAnchor* ps_anchor,
449  const std::string& str_id) {
450  return (ps_anchor->Id == str_id);
451  }
452 
453  /****************************************/
454  /****************************************/
455 
456  void CEmbodiedEntitySpaceHashUpdater::operator()(CAbstractSpaceHash<CEmbodiedEntity>& c_space_hash,
457  CEmbodiedEntity& c_element) {
458  /* Translate the min corner of the bounding box into the map's coordinate */
459  c_space_hash.SpaceToHashTable(m_nMinX, m_nMinY, m_nMinZ, c_element.GetBoundingBox().MinCorner);
460  /* Translate the max corner of the bounding box into the map's coordinate */
461  c_space_hash.SpaceToHashTable(m_nMaxX, m_nMaxY, m_nMaxZ, c_element.GetBoundingBox().MaxCorner);
462  /* Finally, go through the affected cells and update them */
463  for(SInt32 nK = m_nMinZ; nK <= m_nMaxZ; ++nK) {
464  for(SInt32 nJ = m_nMinY; nJ <= m_nMaxY; ++nJ) {
465  for(SInt32 nI = m_nMinX; nI <= m_nMaxX; ++nI) {
466  c_space_hash.UpdateCell(nI, nJ, nK, c_element);
467  }
468  }
469  }
470  }
471 
472  /****************************************/
473  /****************************************/
474 
476  m_cGrid(c_grid) {}
477 
479  try {
480  /* Get cell of bb min corner, clamping it if is out of bounds */
481  m_cGrid.PositionToCell(m_nMinI, m_nMinJ, m_nMinK, c_entity.GetBoundingBox().MinCorner);
482  m_cGrid.ClampCoordinates(m_nMinI, m_nMinJ, m_nMinK);
483  /* Get cell of bb max corner, clamping it if is out of bounds */
484  m_cGrid.PositionToCell(m_nMaxI, m_nMaxJ, m_nMaxK, c_entity.GetBoundingBox().MaxCorner);
485  m_cGrid.ClampCoordinates(m_nMaxI, m_nMaxJ, m_nMaxK);
486  /* Go through cells */
487  for(SInt32 m_nK = m_nMinK; m_nK <= m_nMaxK; ++m_nK) {
488  for(SInt32 m_nJ = m_nMinJ; m_nJ <= m_nMaxJ; ++m_nJ) {
489  for(SInt32 m_nI = m_nMinI; m_nI <= m_nMaxI; ++m_nI) {
490  m_cGrid.UpdateCell(m_nI, m_nJ, m_nK, c_entity);
491  }
492  }
493  }
494  /* Continue with the other entities */
495  return true;
496  }
497  catch(CARGoSException& ex) {
498  THROW_ARGOSEXCEPTION_NESTED("While updating the embodied entity grid for embodied entity \"" << c_entity.GetContext() << c_entity.GetId() << "\"", ex);
499  }
500  }
501 
502  /****************************************/
503  /****************************************/
504 
508  class CSpaceOperationAddEmbodiedEntity : public CSpaceOperationAddEntity {
509  public:
510  void ApplyTo(CSpace& c_space, CEmbodiedEntity& c_entity) {
511  /* Add entity to space */
512  c_space.AddEntity(c_entity);
513  /* Try to add entity to physics engine(s) */
514  c_space.AddEntityToPhysicsEngine(c_entity);
515  }
516  };
517  REGISTER_SPACE_OPERATION(CSpaceOperationAddEntity, CSpaceOperationAddEmbodiedEntity, CEmbodiedEntity);
518 
519  class CSpaceOperationRemoveEmbodiedEntity : public CSpaceOperationRemoveEntity {
520  public:
521  void ApplyTo(CSpace& c_space, CEmbodiedEntity& c_entity) {
522  /* Get a reference to the root entity */
523  CEntity* pcRoot = &c_entity;
524  while(pcRoot->HasParent()) {
525  pcRoot = &pcRoot->GetParent();
526  }
527  /* Remove entity from all physics engines */
528  try {
529  while(c_entity.GetPhysicsModelsNum() > 0) {
530  c_entity.GetPhysicsModel(0).GetEngine().RemoveEntity(*pcRoot);
531  }
532  }
533  catch(CARGoSException& ex) {
534  /*
535  * It is safe to ignore errors because they happen only when an entity
536  * is completely removed from the space. In this case, the body is
537  * first removed from the composable entity, and then the embodied entity
538  * is asked to clear up the physics models. In turn, this last operation
539  * searches for the body component, which is not there anymore.
540  *
541  * It is anyway useful to search for the body component because, when robots
542  * are transferred from an engine to another, only the physics model is to be
543  * removed.
544  */
545  }
546  /* Remove entity from space */
547  c_space.RemoveEntity(c_entity);
548  }
549  };
550  REGISTER_SPACE_OPERATION(CSpaceOperationRemoveEntity, CSpaceOperationRemoveEmbodiedEntity, CEmbodiedEntity);
555  /****************************************/
556  /****************************************/
557 
558 }
T Max(const T &t_v1, const T &t_v2)
Returns the bigger of the two passed arguments.
Definition: general.h:95
signed int SInt32
32-bit signed integer.
Definition: datatypes.h:93
void AddEntity(ENTITY &c_entity)
Adds an entity of the given type.
Definition: space.h:253
A 3D vector class.
Definition: vector3.h:29
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.
CEmbodiedEntityGridUpdater(CGrid< CEmbodiedEntity > &c_grid)
CPhysicsModel::TVector m_tPhysicsModelVector
#define THROW_ARGOSEXCEPTION(message)
This macro throws an ARGoS exception with the passed message.
CVector3 & Rotate(const CQuaternion &c_quaternion)
Rotates this vector by the given quaternion.
Definition: vector3.cpp:25
CQuaternion OffsetOrientation
The initial orientation of the anchor wrt the body coordinate system.
Definition: physics_model.h:49
CQuaternion m_cInitOriginOrientation
The basic entity type.
Definition: entity.h:89
virtual void Reset()
Resets the state of the entity to whatever it was after Init() or the standalone constructor was call...
CQuaternion Orientation
The orientation of the anchor wrt the global coordinate system.
Definition: physics_model.h:53
ticpp::Element TConfigurationNode
The ARGoS configuration XML node.
This entity is a link to a body in the physics engine.
#define THROW_ARGOSEXCEPTION_NESTED(message, nested)
This macro throws an ARGoS exception with the passed message and nesting the passed exception...
virtual bool operator()(CEmbodiedEntity &c_entity)
UInt32 GetPhysicsModelsNum() const
Returns the number of physics models associated to this entity.
REGISTER_SPACE_OPERATION(CSpaceOperationAddEntity, CSpaceOperationAddCFloorEntity, CFloorEntity)
virtual void Init(TConfigurationNode &t_tree)
Initializes the state of the entity from the XML configuration tree.
UInt32 Index
The index of the anchor assigned by the embodied entity.
Definition: physics_model.h:45
virtual bool MoveTo(const CVector3 &c_position, const CQuaternion &c_orientation, bool b_check_only=false)
Moves the entity to the wanted position and orientation.
std::vector< SAnchor * > m_vecEnabledAnchors
unsigned int UInt32
32-bit unsigned integer.
Definition: datatypes.h:97
void CalculateBoundingBox()
Calculates the bounding box of this entity.
virtual ~CEmbodiedEntity()
Class destructor.
std::string Id
The id of the anchor.
Definition: physics_model.h:42
Basic class for an entity that contains other entities.
bool IsAnchorEnabled(const std::string &str_id)
Returns true if the given anchor is enabled, false otherwise.
An anchor related to the body of an entity.
Definition: physics_model.h:38
const SBoundingBox & GetBoundingBox() const
Returns the bounding box of this embodied entity.
CPhysicsModel::TMap m_tPhysicsModelMap
void RemovePhysicsModel(const std::string &str_engine_id)
Removes a physics model from this embodied entity.
The exception that wraps all errors in ARGoS.
const CPhysicsModel & GetPhysicsModel(size_t un_idx) const
Returns a physics model associated to this entity.
virtual void Init(TConfigurationNode &t_tree)
Initializes the state of the entity from the XML configuration tree.
Definition: entity.cpp:40
virtual bool IsCollidingWithSomething() const
Returns true if this entity is colliding with another object.
virtual void AddPhysicsModel(const std::string &str_engine_id, CPhysicsModel &c_physics_model)
Adds a new physics model to this embodied entity.
CEmbodiedEntity(CComposableEntity *pc_parent)
Class constructor.
CVector3 Position
The position of the anchor wrt the global coordinate system.
Definition: physics_model.h:51
SBoundingBox * m_sBoundingBox
CVector3 OffsetPosition
The initial position of the anchor wrt the body coordinate system.
Definition: physics_model.h:47
virtual void AddEntityToPhysicsEngine(CEmbodiedEntity &c_entity)
Definition: space.cpp:163
const SAnchor & GetAnchor(const std::string &str_id) const
Returns the wanted anchor as a const reference.
const std::string & GetId() const
Returns the id of this entity.
Definition: entity.h:157
SAnchor & AddAnchor(const std::string &str_id, const CVector3 &c_rel_position=CVector3(), const CQuaternion &c_rel_orientation=CQuaternion())
Adds an anchor to the embodied entity.
The namespace containing all the ARGoS related code.
Definition: ci_actuator.h:12
std::string GetContext() const
Returns the context of this entity.
Definition: entity.cpp:79
bool operator==(const SAnchor *ps_anchor, const std::string &str_id)
Returns true if the anchor id matches the given id.
void DisableAnchor(const std::string &str_id)
Disables an anchor.
T Min(const T &t_v1, const T &t_v2)
Returns the smaller of the two passed arguments.
Definition: general.h:77
void EnableAnchor(const std::string &str_id)
Enables an anchor.
#define CHECK_CORNER(MINMAX, COORD, OP)
std::map< std::string, SAnchor * > m_mapAnchors