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);
61 for(itArenaItem = itArenaItem.begin(&t_tree);
62 itArenaItem != itArenaItem.end();
64 if(itArenaItem->Value() ==
"distribute") {
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;
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);
521 SetNodeAttribute(tBodyNode,
"orientation", (*pcOrientationGenerator)(bRetry));
523 pcEntity->
Init(tEntityTree);
526 if(pcEmbodiedEntity !=
nullptr) {
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;
unsigned int UInt32
32-bit unsigned integer.
unsigned long long UInt64
64-bit unsigned integer.
float Real
Collects all ARGoS code.
#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.
The namespace containing all the ARGoS related code.
RealNumberGenerator * CreateGenerator(TConfigurationNode &t_tree)
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))
RETURN_VALUE CallEntityOperation(PLUGIN &t_plugin, CEntity &c_entity)
Calls the operation corresponding to the given context and operand Skips the function call if the ope...
bool MatchPattern(const std::string &str_input, const std::string &str_pattern)
Returns true if str_pattern is matched by str_input.
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.
void ParseValues(std::istream &str_input, UInt32 un_num_fields, T *pt_field_buffer, const char ch_delimiter='\n')
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.
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.
std::string ToString(const T &t_value)
Converts the given parameter to a std::string.
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.
const SAnchor & GetOriginAnchor() const
Returns a const reference to the origin anchor associated to this entity.
virtual bool IsCollidingWithSomething() const
Returns true if this entity is colliding with another object.
std::vector< CEntity * > TVector
A vector of entities.
CEntity & GetRootEntity()
Returns the root entity containing this entity.
const std::string & GetId() const
Returns the id of 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.
static CSimulator & GetInstance()
Returns the instance to the CSimulator class.
CLoopFunctions & GetLoopFunctions()
Returns a reference to the loop functions associated to the current experiment.
CMedium::TVector & GetMedia()
Returns the list of currently existing media.
CRandom::CRNG * GetRNG()
Returns the random generator of the "argos" category.
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.
std::map< std::string, CAny, std::less< std::string > > TMapPerType
A map of entities indexed by type description.
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.
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