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>
29 m_unSimulationClock(0),
30 m_pcFloorEntity(nullptr),
31 m_ptPhysicsEngines(nullptr),
51 for(itArenaItem = itArenaItem.begin(&t_tree);
52 itArenaItem != itArenaItem.end();
54 if(itArenaItem->Value() !=
"distribute") {
56 pcEntity->
Init(*itArenaItem);
57 CallEntityOperation<CSpaceOperationAddEntity, CSpace, void>(*
this, *pcEntity);
61 for(itArenaItem = itArenaItem.begin(&t_tree);
62 itArenaItem != itArenaItem.end();
64 if(itArenaItem->Value() ==
"distribute") {
88 CallEntityOperation<CSpaceOperationRemoveEntity, CSpace, void>(*
this, *
m_vecRootEntities.back());
96 const std::string& str_pattern) {
100 t_buffer.push_back(*it);
199 if(vecPotentialEngines.empty()) {
205 for(
size_t i = 0; i < vecPotentialEngines.size(); ++i) {
206 bAdded |= vecPotentialEngines[i]->AddEntity(*pcToAdd);
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() <<
"\"";
215 ossMsg <<
") can house non-movable entity \"" << pcToAdd->
GetId() <<
"\"@(" << cPos <<
").";
220 else if(vecPotentialEngines.size() == 1) {
222 if(!vecPotentialEngines[0]->
AddEntity(*pcToAdd)) {
223 THROW_ARGOSEXCEPTION(
"The matching physics engine (\"" << vecPotentialEngines[0]->GetId() <<
"\"), cannot house movable entity \"" << pcToAdd->
GetId() <<
"\"@(" << cPos <<
").");
228 for(
size_t i = 0; i < vecPotentialEngines.size(); ++i) {
229 if(vecPotentialEngines[i]->
AddEntity(*pcToAdd))
return;
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() <<
"\"";
238 ossMsg <<
") can house movable entity \"" << pcToAdd->
GetId() <<
"\"@(" << cPos <<
").";
284 return CVector3(fRandX, fRandY, fRandZ);
296 m_cStdDev(c_std_dev) {}
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];
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");
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;
336 THROW_ARGOSEXCEPTION(
"Distribute position, method 'grid': trying to place more entities than allowed "
337 "by the 'layout', check your 'quantity' tag");
346 UInt32 m_unNumEntityPlaced;
353 std::string strMethod;
355 if(strMethod ==
"uniform") {
359 if(! (cMin <= cMax)) {
360 THROW_ARGOSEXCEPTION(
"Uniform generator: the min is not less than or equal to max: " << cMin <<
" / " << cMax);
364 else if(strMethod ==
"gaussian") {
370 else if(strMethod ==
"constant") {
375 else if(strMethod ==
"grid") {
380 std::string strLayout;
382 ParseValues<UInt32> (strLayout, 3, unLayout,
',');
393 static CEmbodiedEntity* GetEmbodiedEntity(CEntity* pc_entity) {
395 auto* pcEmbodiedTest =
dynamic_cast<CEmbodiedEntity*
>(pc_entity);
396 if(pcEmbodiedTest !=
nullptr) {
397 return pcEmbodiedTest;
400 auto* pcComposableTest =
dynamic_cast<CComposableEntity*
>(pc_entity);
401 if(pcComposableTest !=
nullptr) {
402 if(pcComposableTest->HasComponent(
"body")) {
403 return &(pcComposableTest->GetComponent<CEmbodiedEntity>(
"body"));
413 static CPositionalEntity* GetPositionalEntity(CEntity* pc_entity) {
415 auto* pcPositionalTest =
dynamic_cast<CPositionalEntity*
>(pc_entity);
416 if(pcPositionalTest !=
nullptr) {
417 return pcPositionalTest;
420 auto* pcComposableTest =
dynamic_cast<CComposableEntity*
>(pc_entity);
421 if(pcComposableTest !=
nullptr) {
422 if(pcComposableTest->HasComponent(
"position")) {
423 return &(pcComposableTest->GetComponent<CPositionalEntity>(
"position"));
437 cPositionNode =
GetNode(t_tree,
"position");
439 cOrientationNode =
GetNode(t_tree,
"orientation");
441 cEntityNode =
GetNode(t_tree,
"entity");
456 itEntity = itEntity.begin(&cEntityNode);
457 if(itEntity == itEntity.end()) {
461 std::string strBaseId;
464 for(
UInt32 i = 0; i < unQuantity; ++i) {
498 if(pcPositionalEntity !=
nullptr) {
502 SetNodeAttribute(tEntityTree,
"orientation", (*pcOrientationGenerator)(bRetry));
504 pcEntity->
Init(tEntityTree);
506 CallEntityOperation<CSpaceOperationAddEntity, CSpace, void>(*
this, *pcEntity);
521 SetNodeAttribute(tBodyNode,
"orientation", (*pcOrientationGenerator)(bRetry));
523 pcEntity->
Init(tEntityTree);
526 if(pcEmbodiedEntity !=
nullptr) {
529 CallEntityOperation<CSpaceOperationAddEntity, CSpace, void>(*
this, *pcEntity);
535 CallEntityOperation<CSpaceOperationRemoveEntity, CSpace, void>(*
this, *pcEntity);
539 if(unTrials > unMaxTrials) {
542 tEntityTree.Value() <<
" with base id \"" <<
543 strBaseId <<
"\". I managed to place only " << i <<
" objects.");
553 THROW_ARGOSEXCEPTION(
"Cannot distribute entities that are not positional nor embodied, and \"" << tEntityTree.Value() <<
"\" is neither.");
560 delete pcPositionGenerator;
561 delete pcOrientationGenerator;
#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.
unsigned long long UInt64
64-bit unsigned integer.
float Real
Collects all ARGoS code.
The namespace containing all the ARGoS related code.
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))
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))
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)
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.
std::vector< CEntity * > TVector
A vector of entities.
const std::string & GetId() const
Returns the id of this entity.
CEntity & GetRootEntity()
Returns the root entity containing this entity.
virtual void Init(TConfigurationNode &t_tree)
Initializes the state of the entity from the XML configuration tree.
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.
CRandom::CRNG * GetRNG()
Returns the random generator of the "argos" category.
CLoopFunctions & GetLoopFunctions()
Returns a reference to the loop functions associated to the current experiment.
static CSimulator & GetInstance()
Returns the instance to the CSimulator class.
CMedium::TVector & GetMedia()
Returns the list of currently existing media.
CPhysicsEngine::TVector & GetPhysicsEngines()
Returns the list of currently existing physics engines.
virtual ~RealNumberGenerator()
virtual CVector3 operator()(bool b_is_retry)=0
ConstantGenerator(const CVector3 &c_value)
virtual CVector3 operator()(bool b_is_retry)
virtual CVector3 operator()(bool b_is_retry)
UniformGenerator(const CVector3 &c_min, const CVector3 &c_max)
virtual CVector3 operator()(bool b_is_retry)
GaussianGenerator(const CVector3 &c_mean, const CVector3 &c_std_dev)
GridGenerator(const CVector3 c_center, const UInt32 un_layout[], const CVector3 c_distances)
virtual CVector3 operator()(bool b_is_retry)
void Distribute(TConfigurationNode &t_tree)
CControllableEntity::TVector m_vecControllableEntities
A vector of controllable entities.
virtual void Init(TConfigurationNode &t_tree)
Initializes the space using the <arena> section of the XML configuration file.
virtual void Destroy()
Destroys the space and all its entities.
virtual void Reset()
Reset the space and all its entities.
bool ControllableEntityIterationEnabled() const
CRange< CVector3 > m_cArenaLimits
Arena limits.
virtual void UpdatePhysics()=0
virtual void Update()
Updates the space.
CSpace()
Class constructor.
CPhysicsEngine::TVector * m_ptPhysicsEngines
A pointer to the list of physics engines.
UInt32 m_unSimulationClock
The current simulation clock.
void GetEntitiesMatching(CEntity::TVector &t_buffer, const std::string &str_pattern)
Returns the entities matching a given pattern.
TControllableEntityIterCBType m_cbControllableEntityIter
Callback for iterating over entities from within the loop functions.
TMapPerTypePerId m_mapEntitiesPerTypePerId
A map of maps of all the simulated entities.
CMedium::TVector * m_ptMedia
A pointer to the list of media.
virtual void ControllableEntityIterationWaitAbort()
If the loop functions do not perform entity iteration in either of the PreStep() or PostStep() functi...
virtual void UpdateControllableEntitiesAct()=0
void AddEntity(ENTITY &c_entity)
Adds an entity of the given type.
void IncreaseSimulationClock(UInt32 un_increase=1)
Increases the simulation clock by the wanted value.
CVector3 m_cArenaSize
Arena size.
CVector3 m_cArenaCenter
Arena center.
CEntity::TVector m_vecRootEntities
A vector of all the entities without a parent.
std::map< std::string, CAny, std::less< std::string > > TMapPerType
A map of entities indexed by type description.
virtual void UpdateMedia()=0
virtual void AddEntityToPhysicsEngine(CEmbodiedEntity &c_entity)
virtual void AddControllableEntity(CControllableEntity &c_entity)
CSimulator & m_cSimulator
CEntity::TVector m_vecEntities
A vector of entities.
virtual void UpdateControllableEntitiesSenseStep()=0
virtual void RemoveControllableEntity(CControllableEntity &c_entity)
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.
CRadians Uniform(const CRange< CRadians > &c_range)
Returns a random value from a uniform distribution.
void SetY(const Real f_y)
Sets the y coordinate of this vector.
Real GetX() const
Returns the x coordinate of this vector.
void SetX(const Real f_x)
Sets the x coordinate of this vector.
void SetZ(const Real f_z)
Sets the z coordinate of this vector.
Real GetY() const
Returns the y coordinate of this vector.
Real GetZ() const
Returns the z coordinate of this vector.
static TYPE * New(const std::string &str_label)
Creates a new object of type TYPE