colored_blob_omnidirectional_camera_rotzonly_sensor.cpp
Go to the documentation of this file.
2 #include <argos3/core/simulator/simulator.h>
3 #include <argos3/core/simulator/space/positional_indices/positional_index.h>
4 #include <argos3/core/simulator/entity/composable_entity.h>
5 #include <argos3/core/simulator/entity/embodied_entity.h>
6 #include <argos3/plugins/simulator/entities/led_entity.h>
7 #include <argos3/plugins/simulator/entities/omnidirectional_camera_equipped_entity.h>
8 #include <argos3/plugins/simulator/media/led_medium.h>
9 
10 namespace argos {
11 
12  /****************************************/
13  /****************************************/
14 
15  class COmnidirectionalCameraLEDCheckOperation : public CPositionalIndex<CLEDEntity>::COperation {
16 
17  public:
18 
21  COmnidirectionalCameraEquippedEntity& c_omnicam_entity,
22  CEmbodiedEntity& c_embodied_entity,
23  CControllableEntity& c_controllable_entity,
24  bool b_show_rays,
25  Real f_noise_std_dev) :
26  m_tBlobs(t_blobs),
27  m_cOmnicamEntity(c_omnicam_entity),
28  m_cEmbodiedEntity(c_embodied_entity),
29  m_cControllableEntity(c_controllable_entity),
30  m_bShowRays(b_show_rays),
31  m_fDistanceNoiseStdDev(f_noise_std_dev),
32  m_pcRNG(nullptr) {
33  m_pcRootSensingEntity = &m_cEmbodiedEntity.GetParent();
34  if(m_fDistanceNoiseStdDev > 0.0f) {
35  m_pcRNG = CRandom::CreateRNG("argos");
36  }
37  }
39  while(! m_tBlobs.empty()) {
40  delete m_tBlobs.back();
41  m_tBlobs.pop_back();
42  }
43  }
44 
45  virtual bool operator()(CLEDEntity& c_led) {
46  /* Process this LED only if it's lit */
47  if(c_led.GetColor() != CColor::BLACK) {
48  if(c_led.HasParent()) {
49  /* Filter out the LEDs belonging to the sensing entity by checking if they share the same parent entity */
50  m_pcRootOfLEDEntity = &c_led.GetParent();
51  while(m_pcRootOfLEDEntity->HasParent()) m_pcRootOfLEDEntity = &m_pcRootOfLEDEntity->GetParent();
52  if(m_pcRootSensingEntity == m_pcRootOfLEDEntity) {
53  return true;
54  }
55  }
56  /* If we are here, it's because the LED must be processed */
57  m_cOcclusionCheckRay.SetEnd(c_led.GetPosition());
58  m_cLEDRelativePos = c_led.GetPosition();
59  m_cLEDRelativePos -= m_cCameraPos;
60  m_cLEDRelativePosXY.Set(m_cLEDRelativePos.GetX(),
61  m_cLEDRelativePos.GetY());
62  if(Abs(m_cLEDRelativePos.GetX()) < m_fGroundHalfRange &&
63  Abs(m_cLEDRelativePos.GetY()) < m_fGroundHalfRange &&
64  m_cLEDRelativePos.GetZ() < m_cCameraPos.GetZ() &&
65  !GetClosestEmbodiedEntityIntersectedByRay(m_sIntersectionItem,
66  m_cOcclusionCheckRay,
67  m_cEmbodiedEntity)) {
68  /* If noise was setup, add it */
69  if(m_fDistanceNoiseStdDev > 0.0f) {
70  m_cLEDRelativePosXY += CVector2(
71  m_cLEDRelativePosXY.Length() * m_pcRNG->Gaussian(m_fDistanceNoiseStdDev),
73  }
75  c_led.GetColor(),
76  NormalizedDifference(m_cLEDRelativePosXY.Angle(), m_cCameraOrient),
77  m_cLEDRelativePosXY.Length() * 100.0f));
78  if(m_bShowRays) {
79  m_cControllableEntity.AddCheckedRay(false, CRay3(m_cCameraPos, c_led.GetPosition()));
80  }
81  }
82  }
83  return true;
84  }
85 
86  void Setup(Real f_ground_half_range) {
87  while(! m_tBlobs.empty()) {
88  delete m_tBlobs.back();
89  m_tBlobs.pop_back();
90  }
91  m_fGroundHalfRange = f_ground_half_range;
92  m_cEmbodiedEntity.GetOriginAnchor().Orientation.ToEulerAngles(m_cCameraOrient, m_cTmp1, m_cTmp2);
93  m_cCameraPos = m_cEmbodiedEntity.GetOriginAnchor().Position;
94  m_cCameraPos += m_cOmnicamEntity.GetOffset();
95  m_cOcclusionCheckRay.SetStart(m_cCameraPos);
96  }
97 
98  private:
99 
101  COmnidirectionalCameraEquippedEntity& m_cOmnicamEntity;
102  CEmbodiedEntity& m_cEmbodiedEntity;
103  CControllableEntity& m_cControllableEntity;
104  Real m_fGroundHalfRange;
105  bool m_bShowRays;
106  CEntity* m_pcRootSensingEntity;
107  CEntity* m_pcRootOfLEDEntity;
108  CVector3 m_cCameraPos;
109  CRadians m_cCameraOrient;
110  CRadians m_cTmp1, m_cTmp2;
111  CVector3 m_cLEDRelativePos;
112  CVector2 m_cLEDRelativePosXY;
113  SEmbodiedEntityIntersectionItem m_sIntersectionItem;
114  CRay3 m_cOcclusionCheckRay;
115  Real m_fDistanceNoiseStdDev;
116  CRandom::CRNG* m_pcRNG;
117  };
118 
119  /****************************************/
120  /****************************************/
121 
123  m_pcOmnicamEntity(nullptr),
124  m_pcControllableEntity(nullptr),
125  m_pcEmbodiedEntity(nullptr),
126  m_pcLEDIndex(nullptr),
127  m_pcEmbodiedIndex(nullptr),
128  m_bShowRays(false) {
129  }
130 
131  /****************************************/
132  /****************************************/
133 
135  }
136 
137  /****************************************/
138  /****************************************/
139 
141  /* Get omndirectional camera equipped entity */
142  m_pcOmnicamEntity = &(c_entity.GetComponent<COmnidirectionalCameraEquippedEntity>("omnidirectional_camera"));
143  /* Get controllable entity */
144  m_pcControllableEntity = &(c_entity.GetComponent<CControllableEntity>("controller"));
145  /* Get embodied entity */
146  m_pcEmbodiedEntity = &(c_entity.GetComponent<CEmbodiedEntity>("body"));
147  }
148 
149  /****************************************/
150  /****************************************/
151 
153  try {
154  /* Parent class init */
156  /* Show rays? */
157  GetNodeAttributeOrDefault(t_tree, "show_rays", m_bShowRays, m_bShowRays);
158  /* Parse noise */
159  Real fDistanceNoiseStdDev = 0;
160  GetNodeAttributeOrDefault(t_tree, "noise_std_dev", fDistanceNoiseStdDev, fDistanceNoiseStdDev);
161  /* Get LED medium from id specified in the XML */
162  std::string strMedium;
163  GetNodeAttribute(t_tree, "medium", strMedium);
164  m_pcLEDIndex = &(CSimulator::GetInstance().GetMedium<CLEDMedium>(strMedium).GetIndex());
165  /* Create check operation */
171  m_bShowRays,
172  fDistanceNoiseStdDev);
173  }
174  catch(CARGoSException& ex) {
175  THROW_ARGOSEXCEPTION_NESTED("Error initializing the colored blob omnidirectional camera rotzonly sensor", ex);
176  }
177  /* sensor is disabled by default */
178  Disable();
179  }
180 
181  /****************************************/
182  /****************************************/
183 
185  /* sensor is disabled--nothing to do */
186  if (IsDisabled()) {
187  return;
188  }
189 
190  /* Increase data counter */
192  /* Calculate range on the ground */
193  CVector3 cCameraPos = m_pcOmnicamEntity->GetOffset();
195  Real fGroundHalfRange = cCameraPos.GetZ() * Tan(m_pcOmnicamEntity->GetAperture());
196  /* Prepare the operation */
197  m_pcOperation->Setup(fGroundHalfRange);
198  /* Go through LED entities in box range */
199  m_pcLEDIndex->ForEntitiesInBoxRange(
200  CVector3(cCameraPos.GetX(),
201  cCameraPos.GetY(),
202  cCameraPos.GetZ() * 0.5f),
203  CVector3(fGroundHalfRange, fGroundHalfRange, cCameraPos.GetZ() * 0.5f),
204  *m_pcOperation);
205  }
206 
207  /****************************************/
208  /****************************************/
209 
211  m_sReadings.Counter = 0;
212  m_sReadings.BlobList.clear();
213  }
214 
215  /****************************************/
216  /****************************************/
217 
219  delete m_pcOperation;
220  }
221 
222  /****************************************/
223  /****************************************/
224 
228  }
229 
230  /****************************************/
231  /****************************************/
232 
236  }
237 
238  /****************************************/
239  /****************************************/
240 
242  "colored_blob_omnidirectional_camera", "rot_z_only",
243  "Carlo Pinciroli [ilpincy@gmail.com]",
244  "1.0",
245 
246  "A generic omnidirectional camera sensor to detect colored blobs.",
247  "This sensor accesses an omnidirectional camera that detects colored blobs. The\n"
248  "sensor returns a list of blobs, each defined by a color and a position with\n"
249  "respect to the robot reference point on the ground. In controllers, you must\n"
250  "include the ci_colored_blob_omnidirectional_camera_sensor.h header.\n\n"
251 
252  "This sensor is disabled by default, and must be enabled before it can be\n"
253  "used.\n\n"
254 
255  "REQUIRED XML CONFIGURATION\n\n"
256 
257  " <controllers>\n"
258  " ...\n"
259  " <my_controller ...>\n"
260  " ...\n"
261  " <sensors>\n"
262  " ...\n"
263  " <colored_blob_omnidirectional_camera implementation=\"rot_z_only\"\n"
264  " medium=\"leds\" />\n"
265  " ...\n"
266  " </sensors>\n"
267  " ...\n"
268  " </my_controller>\n"
269  " ...\n"
270  " </controllers>\n\n"
271 
272  "The 'medium' attribute must be set to the id of the leds medium declared in the\n"
273  "<media> section.\n\n"
274 
275  "OPTIONAL XML CONFIGURATION\n\n"
276 
277  "It is possible to draw the rays shot by the camera sensor in the OpenGL\n"
278  "visualization. This can be useful for sensor debugging but also to understand\n"
279  "what's wrong in your controller. In OpenGL, the rays are drawn in cyan when\n"
280  "they are not obstructed and in purple when they are. In case a ray is\n"
281  "obstructed, a black dot is drawn where the intersection occurred.\n"
282  "To turn this functionality on, add the attribute \"show_rays\" as in this\n"
283  "example:\n\n"
284 
285  " <controllers>\n"
286  " ...\n"
287  " <my_controller ...>\n"
288  " ...\n"
289  " <sensors>\n"
290  " ...\n"
291  " <colored_blob_omnidirectional_camera implementation=\"rot_z_only\"\n"
292  " medium=\"leds\" />\n"
293  " show_rays=\"true\" />\n"
294  " ...\n"
295  " </sensors>\n"
296  " ...\n"
297  " </my_controller>\n"
298  " ...\n"
299  " </controllers>\n\n"
300 
301  "It is possible to add uniform noise to the blobs, thus matching the\n"
302  "characteristics of a real robot better. This can be done with the attribute\n"
303  "\"noise_std_dev\".\n\n"
304  " <controllers>\n"
305  " ...\n"
306  " <my_controller ...>\n"
307  " ...\n"
308  " <sensors>\n"
309  " ...\n"
310  " <colored_blob_omnidirectional_camera implementation=\"rot_z_only\"\n"
311  " medium=\"leds\" />\n"
312  " noise_std_dev=\"0.1\" />\n"
313  " ...\n"
314  " </sensors>\n"
315  " ...\n"
316  " </my_controller>\n"
317  " ...\n"
318  " </controllers>\n\n"
319 
320  "OPTIMIZATION HINTS\n\n"
321 
322  "1. For small swarms, enabling the sensor (and therefore causing ARGoS to\n"
323  " update its readings each timestep) unconditionally does not impact performance too\n"
324  " much. For large swarms, it can impact performance, and selectively\n"
325  " enabling/disabling the sensor according to when each individual robot needs it\n"
326  " (e.g., only when it is looking for an LED equipped entity) can increase performance\n"
327  " by only requiring ARGoS to update the readings on timesteps they will be used.\n",
328 
329  "Usable"
330  );
331 
332 }
#define THROW_ARGOSEXCEPTION_NESTED(message, nested)
This macro throws an ARGoS exception with the passed message and nesting the passed exception.
float Real
Collects all ARGoS code.
Definition: datatypes.h:39
The namespace containing all the ARGoS related code.
Definition: ci_actuator.h:12
bool GetClosestEmbodiedEntityIntersectedByRay(SEmbodiedEntityIntersectionItem &s_item, const CRay3 &c_ray)
Returns the closest intersection with an embodied entity to the ray start.
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.
CRadians NormalizedDifference(const CRadians &c_angle1, const CRadians &c_angle2)
Calculates the normalized difference between the given angles.
Definition: angles.h:510
REGISTER_SENSOR(CEPuckProximityDefaultSensor, "epuck_proximity", "default", "Danesh Tarapore [daneshtarapore@gmail.com]", "1.0", "The E-Puck proximity sensor.", "This sensor accesses the epuck proximity sensor. For a complete description\n" "of its usage, refer to the ci_epuck_proximity_sensor.h interface. For the XML\n" "configuration, refer to the default proximity sensor.\n", "Usable")
ticpp::Element TConfigurationNode
The ARGoS configuration XML node.
Real Tan(const CRadians &c_radians)
Computes the tangent of the passed value in radians.
Definition: angles.h:604
T Abs(const T &t_v)
Returns the absolute value of the passed argument.
Definition: general.h:25
void GetNodeAttribute(TConfigurationNode &t_node, const std::string &str_attribute, T &t_buffer)
Returns the value of a node's attribute.
virtual void Enable()
Enables updating of sensor information in the event loop.
Definition: ci_sensor.h:78
virtual void Init(TConfigurationNode &t_node)
Initializes the sensor from the XML configuration tree.
Definition: ci_sensor.h:54
bool IsDisabled() const
Definition: ci_sensor.h:86
virtual void Disable()
Disables updating of sensor information in the event loop.
Definition: ci_sensor.h:83
Basic class for an entity that contains other entities.
CEntity & GetComponent(const std::string &str_component)
Returns the component with the passed string label.
An entity that contains a pointer to the user-defined controller.
void AddCheckedRay(bool b_obstructed, const CRay3 &c_ray)
Adds a ray to the list of checked rays.
This entity is a link to a body in the physics engine.
const SAnchor & GetOriginAnchor() const
Returns a const reference to the origin anchor associated to this entity.
The basic entity type.
Definition: entity.h:90
void Disable()
Disables the entity.
Definition: entity.h:275
void Enable()
Enables the entity.
Definition: entity.h:265
CComposableEntity & GetParent()
Returns this entity's parent.
Definition: entity.cpp:91
bool HasParent() const
Returns true if this entity has a parent.
Definition: entity.h:171
const CVector3 & GetPosition() const
CQuaternion Orientation
The orientation of the anchor wrt the global coordinate system.
Definition: physics_model.h:53
CVector3 Position
The position of the anchor wrt the global coordinate system.
Definition: physics_model.h:51
T & GetMedium(const std::string &str_id)
Returns a reference to a medium.
Definition: simulator.h:129
static CSimulator & GetInstance()
Returns the instance to the CSimulator class.
Definition: simulator.cpp:78
A data structure that contains positional entities.
The exception that wraps all errors in ARGoS.
static CColor BLACK
Definition: color.h:29
It defines the basic type CRadians, used to store an angle value in radians.
Definition: angles.h:42
static const CRange< CRadians > UNSIGNED_RANGE
The unsigned normalization range [0:TWO_PI].
Definition: angles.h:274
void ToEulerAngles(CRadians &c_z_angle, CRadians &c_y_angle, CRadians &c_x_angle) const
Definition: quaternion.h:172
void SetEnd(const CVector3 &c_end)
Definition: ray3.h:57
void SetStart(const CVector3 &c_start)
Definition: ray3.h:53
static CRNG * CreateRNG(const std::string &str_category)
Creates a new RNG inside the given category.
Definition: rng.cpp:347
The RNG.
Definition: rng.h:90
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 2D vector class.
Definition: vector2.h:27
Real Length() const
Returns the length of this vector.
Definition: vector2.h:166
CRadians Angle() const
Returns the angle of this vector.
Definition: vector2.h:185
void Set(Real f_x, Real f_y)
Sets the vector contents from Cartesian coordinates.
Definition: vector2.h:127
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
std::vector< SBlob * > TBlobList
Vector of pointers to colored blobs.
An SBlob represents a generic colored 2D segment in the image.
COmnidirectionalCameraLEDCheckOperation(CCI_ColoredBlobOmnidirectionalCameraSensor::TBlobList &t_blobs, COmnidirectionalCameraEquippedEntity &c_omnicam_entity, CEmbodiedEntity &c_embodied_entity, CControllableEntity &c_controllable_entity, bool b_show_rays, Real f_noise_std_dev)
virtual void Disable()
Disables updating of sensor information in the event loop.
virtual void Reset()
Resets the sensor to the state it had just after Init().
virtual void Enable()
Enables updating of sensor information in the event loop.
virtual void Update()
Updates the state of the entity associated to this sensor, if the sensor is currently enabled.
virtual void SetRobot(CComposableEntity &c_entity)
Sets the entity associated to this sensor.
virtual void Init(TConfigurationNode &t_tree)
Initializes the sensor from the XML configuration tree.
const CColor & GetColor() const
Returns the current color of the LED.
Definition: led_entity.h:58
const CRadians & GetAperture() const
Returns the aperture of the visibility cone of the omnidirectional camera.
const CVector3 & GetOffset() const
Returns the offset of the omnidirectional camera with respect to the reference point.