rab_medium.cpp
Go to the documentation of this file.
1 #include "rab_medium.h"
2 #include <argos3/core/simulator/entity/embodied_entity.h>
3 #include <argos3/core/simulator/simulator.h>
4 #include <argos3/core/simulator/space/space.h>
5 #include <argos3/core/simulator/space/positional_indices/grid.h>
6 #include <argos3/core/utility/configuration/argos_exception.h>
7 #include <argos3/core/utility/logging/argos_log.h>
8 
9 namespace argos {
10 
11  /****************************************/
12  /****************************************/
13 
15  m_bCheckOcclusions(true) {
16  }
17 
18  /****************************************/
19  /****************************************/
20 
22  }
23 
24  /****************************************/
25  /****************************************/
26 
28  try {
29  CMedium::Init(t_tree);
30  /* Check occlusions? */
31  GetNodeAttributeOrDefault(t_tree, "check_occlusions", m_bCheckOcclusions, m_bCheckOcclusions);
32  /* Get the positional index method */
33  std::string strPosIndexMethod("grid");
34  GetNodeAttributeOrDefault(t_tree, "index", strPosIndexMethod, strPosIndexMethod);
35  /* Get the arena center and size */
36  CVector3 cArenaCenter;
37  CVector3 cArenaSize;
38  TConfigurationNode& tArena = GetNode(CSimulator::GetInstance().GetConfigurationRoot(), "arena");
39  GetNodeAttribute(tArena, "size", cArenaSize);
40  GetNodeAttributeOrDefault(tArena, "center", cArenaCenter, cArenaCenter);
41  /* Create the positional index for embodied entities */
42  if(strPosIndexMethod == "grid") {
43  size_t punGridSize[3];
44  if(!NodeAttributeExists(t_tree, "grid_size")) {
45  punGridSize[0] = static_cast<size_t>(cArenaSize.GetX());
46  punGridSize[1] = static_cast<size_t>(cArenaSize.GetY());
47  punGridSize[2] = static_cast<size_t>(cArenaSize.GetZ());
48  }
49  else {
50  std::string strPosGridSize;
51  GetNodeAttribute(t_tree, "grid_size", strPosGridSize);
52  ParseValues<size_t>(strPosGridSize, 3, punGridSize, ',');
53  }
55  cArenaCenter - cArenaSize * 0.5f, cArenaCenter + cArenaSize * 0.5f,
56  punGridSize[0], punGridSize[1], punGridSize[2]);
57  m_pcRABEquippedEntityGridUpdateOperation = new CRABEquippedEntityGridEntityUpdater(*pcGrid);
58  pcGrid->SetUpdateEntityOperation(m_pcRABEquippedEntityGridUpdateOperation);
59  m_pcRABEquippedEntityIndex = pcGrid;
60  }
61  else {
62  THROW_ARGOSEXCEPTION("Unknown method \"" << strPosIndexMethod << "\" for the positional index.");
63  }
64  }
65  catch(CARGoSException& ex) {
66  THROW_ARGOSEXCEPTION_NESTED("Error in initialization of the range-and-bearing medium", ex);
67  }
68  }
69 
70  /****************************************/
71  /****************************************/
72 
74  Update();
75  }
76 
77  /****************************************/
78  /****************************************/
79 
81  /* Reset positional index of RAB entities */
82  m_pcRABEquippedEntityIndex->Reset();
83  /* Delete routing table */
84  for(TRoutingTable::iterator it = m_tRoutingTable.begin();
85  it != m_tRoutingTable.end();
86  ++it) {
87  it->second.clear();
88  }
89  }
90 
91  /****************************************/
92  /****************************************/
93 
95  delete m_pcRABEquippedEntityIndex;
96  if(m_pcRABEquippedEntityGridUpdateOperation != nullptr) {
97  delete m_pcRABEquippedEntityGridUpdateOperation;
98  }
99  }
100 
101  /****************************************/
102  /****************************************/
103 
104  static size_t HashRABPair(const std::pair<CRABEquippedEntity*, CRABEquippedEntity*>& c_pair) {
105  return
106  reinterpret_cast<size_t>(c_pair.first) ^
107  reinterpret_cast<size_t>(c_pair.second);
108  }
109 
111  /* Update positional index of RAB entities */
112  m_pcRABEquippedEntityIndex->Update();
113  /* Delete routing table */
114  for(TRoutingTable::iterator it = m_tRoutingTable.begin();
115  it != m_tRoutingTable.end();
116  ++it) {
117  it->second.clear();
118  }
119  /* This map contains the pairs that have already been checked */
120  unordered_map<ssize_t, std::pair<CRABEquippedEntity*, CRABEquippedEntity*> > mapPairsAlreadyChecked;
121  /* Iterator for the above structure */
122  unordered_map<ssize_t, std::pair<CRABEquippedEntity*, CRABEquippedEntity*> >::iterator itPair;
123  /* Used as test key */
124  std::pair<CRABEquippedEntity*, CRABEquippedEntity*> cTestKey;
125  /* Used as hash for the test key */
126  UInt64 unTestHash;
127  /* The ray to use for occlusion checking */
128  CRay3 cOcclusionCheckRay;
129  /* Buffer for the communicating entities */
131  /* Buffer to store the intersection data */
132  SEmbodiedEntityIntersectionItem sIntersectionItem;
133  /* The distance between two RABs in line of sight */
134  Real fDistance;
135  /* Go through the RAB entities */
136  for(TRoutingTable::iterator it = m_tRoutingTable.begin();
137  it != m_tRoutingTable.end();
138  ++it) {
139  /* Get a reference to the current RAB entity */
140  CRABEquippedEntity& cRAB = *reinterpret_cast<CRABEquippedEntity*>(GetSpace().GetEntityVector()[it->first]);
141  /* Initialize the occlusion check ray start to the position of the robot */
142  cOcclusionCheckRay.SetStart(cRAB.GetPosition());
143  /* For each RAB entity, get the list of RAB entities in range */
144  cOtherRABs.clear();
145  m_pcRABEquippedEntityIndex->GetEntitiesAt(cOtherRABs, cRAB.GetPosition());
146  /* Go through the RAB entities in range */
147  for(CSet<CRABEquippedEntity*>::iterator it2 = cOtherRABs.begin();
148  it2 != cOtherRABs.end();
149  ++it2) {
150  /* Get a reference to the RAB entity */
151  CRABEquippedEntity& cOtherRAB = **it2;
152  /* First, make sure the entities are not the same */
153  if(&cRAB != &cOtherRAB) {
154  /* Proceed if the pair has not been checked already */
155  if(&cRAB < &cOtherRAB) {
156  cTestKey.first = &cRAB;
157  cTestKey.second = &cOtherRAB;
158  }
159  else {
160  cTestKey.first = &cOtherRAB;
161  cTestKey.second = &cRAB;
162  }
163  unTestHash = HashRABPair(cTestKey);
164  itPair = mapPairsAlreadyChecked.find(unTestHash);
165  if(itPair == mapPairsAlreadyChecked.end() || /* Pair does not exist */
166  itPair->second.first != cTestKey.first || /* Pair exists, but first RAB involved is different */
167  itPair->second.second != cTestKey.second) { /* Pair exists, but second RAB involved is different */
168  /* Mark this pair as already checked */
169  mapPairsAlreadyChecked[unTestHash] = cTestKey;
170  /* Proceed if the message size is compatible */
171  if(cRAB.GetMsgSize() == cOtherRAB.GetMsgSize()) {
172  /* Proceed if the two entities are not obstructed by another object */
173  cOcclusionCheckRay.SetEnd(cOtherRAB.GetPosition());
174  if((!m_bCheckOcclusions) ||
175  (!GetClosestEmbodiedEntityIntersectedByRay(sIntersectionItem,
176  cOcclusionCheckRay,
177  cRAB.GetEntityBody())) ||
178  (&cOtherRAB.GetEntityBody() == sIntersectionItem.IntersectedEntity)) {
179  /* If we get here, the two RAB entities are in direct line of sight */
180  /* cRAB can receive cOtherRAB's message if it is in range, and viceversa */
181  /* Calculate square distance */
182  fDistance = cOcclusionCheckRay.GetLength();
183  if(fDistance < cOtherRAB.GetRange()) {
184  /* cRAB receives cOtherRAB's message */
185  m_tRoutingTable[cRAB.GetIndex()].insert(&cOtherRAB);
186  }
187  if(fDistance < cRAB.GetRange()) {
188  /* cOtherRAB receives cRAB's message */
189  m_tRoutingTable[cOtherRAB.GetIndex()].insert(&cRAB);
190  }
191  } // occlusion found?
192  } // is msg size the same?
193  } // is check necessary?
194  } // are entities the same?
195  } // for entities in range
196  } // for routing table
197  }
198 
199  /****************************************/
200  /****************************************/
201 
203  m_tRoutingTable.insert(
204  std::make_pair<ssize_t, CSet<CRABEquippedEntity*,SEntityComparator> >(
206  m_pcRABEquippedEntityIndex->AddEntity(c_entity);
207  m_pcRABEquippedEntityIndex->Update();
208  }
209 
210  /****************************************/
211  /****************************************/
212 
214  m_pcRABEquippedEntityIndex->RemoveEntity(c_entity);
215  m_pcRABEquippedEntityIndex->Update();
216  TRoutingTable::iterator it = m_tRoutingTable.find(c_entity.GetIndex());
217  if(it != m_tRoutingTable.end())
218  m_tRoutingTable.erase(it);
219  }
220 
221  /****************************************/
222  /****************************************/
223 
225  TRoutingTable::const_iterator it = m_tRoutingTable.find(c_entity.GetIndex());
226  if(it != m_tRoutingTable.end()) {
227  return it->second;
228  }
229  else {
230  THROW_ARGOSEXCEPTION("RAB entity \"" << c_entity.GetContext() << c_entity.GetId() << "\" is not managed by the RAB medium \"" << GetId() << "\"");
231  }
232  }
233 
234  /****************************************/
235  /****************************************/
236 
238  "range_and_bearing",
239  "Carlo Pinciroli [ilpincy@gmail.com]",
240  "1.0",
241  "It simulates the communication across range-and-bearing-equipped robots.",
242  "This medium is required to simulate communication across range-and-bearing-\n"
243  "equipped robots. You need to add it to the <media> section every time you add\n"
244  "a range-and-bearing-equipped entity whose controller has a range-and-bearing\n"
245  "device activated.\n\n"
246  "REQUIRED XML CONFIGURATION\n\n"
247  "<range_and_bearing id=\"rab\" />\n\n"
248  "OPTIONAL XML CONFIGURATION\n\n"
249  "By default, the RAB medium requires two robots to be in direct line-of-sight in\n"
250  "order to be able to exchange messages. You can toggle this behavior on or off\n"
251  "through the 'check_occlusions' attribute:\n\n"
252  "<range_and_bearing id=\"rab\" check_occlusions=\"false\" />\n\n",
253  "Under development"
254  );
255 
256  /****************************************/
257  /****************************************/
258 
259 }
#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 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
REGISTER_MEDIUM(CDirectionalLEDMedium, "directional_led", "Michael Allwright [allsey87@gmail.com]", "1.0", "Manages directional LED entities.", "This medium is required to manage the directional LED entities, so that\n" "the associated camera sensors can find them. If you use a camera sensor,\n" "you must add this medium the sensors XML configuration.\n\n" "REQUIRED XML CONFIGURATION\n\n" "<directional_led id=\"led\" />\n\n" "OPTIONAL XML CONFIGURATION\n\n" "None for the time being\n", "Under development")
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.
bool GetClosestEmbodiedEntityIntersectedByRay(SEmbodiedEntityIntersectionItem &s_item, const CRay3 &c_ray)
Returns the closest intersection with an embodied entity to the ray start.
bool NodeAttributeExists(TConfigurationNode &t_node, const std::string &str_attribute)
Returns true if the specified attribute of a node exists.
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.
void GetNodeAttribute(TConfigurationNode &t_node, const std::string &str_attribute, T &t_buffer)
Returns the value of a node's attribute.
const std::string & GetId() const
Returns the id of this entity.
Definition: entity.h:157
std::string GetContext() const
Returns the context of this entity.
Definition: entity.cpp:79
ssize_t GetIndex() const
Returns the entity index.
Definition: entity.h:234
const CVector3 & GetPosition() const
virtual void Init(TConfigurationNode &t_tree)
Initialized the medium.
Definition: medium.cpp:16
CSpace & GetSpace()
Returns a reference to the ARGoS space.
Definition: medium.h:92
const std::string & GetId() const
Returns the id of this medium.
Definition: medium.h:76
static CSimulator & GetInstance()
Returns the instance to the CSimulator class.
Definition: simulator.cpp:78
void SetUpdateEntityOperation(CEntityOperation *pc_operation)
Definition: grid_impl.h:907
CEntity::TVector & GetEntityVector()
Returns a vector of all the entities in the space.
Definition: space.h:136
The exception that wraps all errors in ARGoS.
The CSet iterator.
Definition: set.h:39
Defines a very simple double-linked list that stores unique elements.
Definition: set.h:101
iterator begin() const
Returns an iterator to the first element.
Definition: set.h:389
void clear()
Erases the contents of the list.
Definition: set.h:351
iterator end() const
Returns an invalid iterator.
Definition: set.h:397
void SetEnd(const CVector3 &c_end)
Definition: ray3.h:57
Real GetLength() const
Definition: ray3.h:96
void SetStart(const CVector3 &c_start)
Definition: ray3.h:53
A 3D vector class.
Definition: vector3.h:31
Real GetX() const
Returns the x coordinate of this vector.
Definition: vector3.h:105
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
CEmbodiedEntity & GetEntityBody()
virtual void Update()
Updates the state of this medium.
Definition: rab_medium.cpp:110
void AddEntity(CRABEquippedEntity &c_entity)
Adds the specified entity to the list of managed entities.
Definition: rab_medium.cpp:202
virtual void Destroy()
Undoes whatever was done by Init().
Definition: rab_medium.cpp:94
const CSet< CRABEquippedEntity *, SEntityComparator > & GetRABsCommunicatingWith(CRABEquippedEntity &c_entity) const
Returns an immutable vector of RAB entities that can communicated with the given entity.
Definition: rab_medium.cpp:224
CRABMedium()
Class constructor.
Definition: rab_medium.cpp:14
virtual void PostSpaceInit()
Executes extra initialization activities after the space has been initialized.
Definition: rab_medium.cpp:73
void RemoveEntity(CRABEquippedEntity &c_entity)
Removes the specified entity from the list of managed entities.
Definition: rab_medium.cpp:213
virtual ~CRABMedium()
Class destructor.
Definition: rab_medium.cpp:21
virtual void Reset()
Resets the resource.
Definition: rab_medium.cpp:80
virtual void Init(TConfigurationNode &t_tree)
Initialized the medium.
Definition: rab_medium.cpp:27