ARGoS 3
A parallel, multi-engine simulator for swarm robotics
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
10namespace argos {
11
12 /****************************************/
13 /****************************************/
14
15 class COmnidirectionalCameraLEDCheckOperation : public CPositionalIndex<CLEDEntity>::COperation {
16
17 public:
18
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() &&
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
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? */
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 */
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),
205 }
206
207 /****************************************/
208 /****************************************/
209
214
215 /****************************************/
216 /****************************************/
217
221
222 /****************************************/
223 /****************************************/
224
229
230 /****************************************/
231 /****************************************/
232
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}
float Real
Collects all ARGoS code.
Definition datatypes.h:39
#define THROW_ARGOSEXCEPTION_NESTED(message, nested)
This macro throws an ARGoS exception with the passed message and nesting the passed exception.
#define REGISTER_SENSOR(CLASSNAME, LABEL, IMPLEMENTATION, AUTHOR, VERSION, BRIEF_DESCRIPTION, LONG_DESCRIPTION, STATUS)
Registers a new sensor model inside ARGoS.
Definition sensor.h:63
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
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.
CVector3 Position
The position of the anchor wrt the global coordinate system.
static CSimulator & GetInstance()
Returns the instance to the CSimulator class.
Definition simulator.cpp:78
T & GetMedium(const std::string &str_id)
Returns a reference to a medium.
Definition simulator.h:129
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.