ARGoS 3
A parallel, multi-engine simulator for swarm robotics
eyebot_entity.cpp
Go to the documentation of this file.
1
7#include "eyebot_entity.h"
8
9#include <argos3/core/simulator/space/space.h>
10#include <argos3/core/simulator/entity/controllable_entity.h>
11#include <argos3/core/simulator/entity/embodied_entity.h>
12#include <argos3/plugins/simulator/entities/led_equipped_entity.h>
13#include <argos3/plugins/simulator/entities/light_sensor_equipped_entity.h>
14#include <argos3/plugins/simulator/entities/perspective_camera_equipped_entity.h>
15#include <argos3/plugins/simulator/entities/proximity_sensor_equipped_entity.h>
16#include <argos3/plugins/simulator/entities/quadrotor_entity.h>
17#include <argos3/plugins/simulator/entities/rab_equipped_entity.h>
18#include <argos3/plugins/simulator/entities/battery_equipped_entity.h>
19
20namespace argos {
21
22 /****************************************/
23 /****************************************/
24
25 static const Real BODY_HEIGHT = 0.566f;
26 static const Real BODY_RADIUS = 0.25f;
27 static const Real LED_RING_RADIUS = BODY_RADIUS + 0.005;
28 static const Real LED_LOWER_RING_ELEVATION = 0.1535f;
29 static const Real LED_UPPER_RING_ELEVATION = 0.1635f;
30 static const CRadians LED_ANGLE_SLICE = CRadians(3.14159265358979323846264338327950288 / 8.0);
31 static const CRadians HALF_LED_ANGLE_SLICE = LED_ANGLE_SLICE * 0.5f;
32 static const Real PROXIMITY_SENSOR_RING_ELEVATION = LED_UPPER_RING_ELEVATION;
33 static const Real PROXIMITY_SENSOR_RING_RADIUS = LED_RING_RADIUS;
34 static const CRadians PROXIMITY_SENSOR_RING_START_ANGLE = CRadians((ARGOS_PI / 12.0f) * 0.5f);
35 static const Real PROXIMITY_SENSOR_RING_RANGE = 3.0f;
36
37 /****************************************/
38 /****************************************/
39
41 CComposableEntity(nullptr),
42 m_pcControllableEntity(nullptr),
43 m_pcEmbodiedEntity(nullptr),
44 m_pcLEDEquippedEntity(nullptr),
45 m_pcLightSensorEquippedEntity(nullptr),
46 m_pcPerspectiveCameraEquippedEntity(nullptr),
47 m_pcProximitySensorEquippedEntity(nullptr),
48 m_pcQuadRotorEntity(nullptr),
49 m_pcRABEquippedEntity(nullptr),
50 m_pcBatteryEquippedEntity(nullptr) {
51 }
52
53 /****************************************/
54 /****************************************/
55
56 CEyeBotEntity::CEyeBotEntity(const std::string& str_id,
57 const std::string& str_controller_id,
58 const CVector3& c_position,
59 const CQuaternion& c_orientation,
60 Real f_rab_range,
61 size_t un_rab_data_size,
62 const std::string& str_bat_model,
63 const CRadians& c_perspcam_aperture,
64 Real f_perspcam_focal_length,
65 Real f_perspcam_range) :
66 CComposableEntity(nullptr, str_id),
67 m_pcControllableEntity(nullptr),
68 m_pcEmbodiedEntity(nullptr),
69 m_pcLEDEquippedEntity(nullptr),
70 m_pcLightSensorEquippedEntity(nullptr),
71 m_pcPerspectiveCameraEquippedEntity(nullptr),
72 m_pcProximitySensorEquippedEntity(nullptr),
73 m_pcQuadRotorEntity(nullptr),
74 m_pcRABEquippedEntity(nullptr),
75 m_pcBatteryEquippedEntity(nullptr) {
76 try {
77 /*
78 * Create and init components
79 */
80 /*
81 * Embodied entity
82 * Better to put this first, because many other entities need this one
83 */
84 m_pcEmbodiedEntity = new CEmbodiedEntity(this, "body_0", c_position, c_orientation);
85 AddComponent(*m_pcEmbodiedEntity);
86 /* Quadrotor entity */
87 m_pcQuadRotorEntity = new CQuadRotorEntity(this, "quadrotor_0");
88 AddComponent(*m_pcQuadRotorEntity);
89 /* LED equipped entity, with LEDs [0-11] and beacon [12] */
90 m_pcLEDEquippedEntity = new CLEDEquippedEntity(this, "leds_0");
91 m_pcLEDEquippedEntity->AddLEDRing(
92 CVector3(0.0f, 0.0f, LED_LOWER_RING_ELEVATION),
93 LED_RING_RADIUS,
94 HALF_LED_ANGLE_SLICE,
95 16,
96 m_pcEmbodiedEntity->GetOriginAnchor());
97 m_pcLEDEquippedEntity->AddLEDRing(
98 CVector3(0.0f, 0.0f, LED_UPPER_RING_ELEVATION),
99 LED_RING_RADIUS,
100 HALF_LED_ANGLE_SLICE,
101 16,
102 m_pcEmbodiedEntity->GetOriginAnchor());
103 CVector3 cLEDPos(LED_RING_RADIUS * 0.7f,
104 0.0f,
105 LED_LOWER_RING_ELEVATION - 0.01f);
106 cLEDPos.RotateZ(3.0f * CRadians::PI_OVER_FOUR);
107 m_pcLEDEquippedEntity->AddLED(
108 cLEDPos,
109 m_pcEmbodiedEntity->GetOriginAnchor());
110 AddComponent(*m_pcLEDEquippedEntity);
111 /* Proximity sensor equipped entity */
112 m_pcProximitySensorEquippedEntity =
114 "proximity_0");
115 AddComponent(*m_pcProximitySensorEquippedEntity);
116 m_pcProximitySensorEquippedEntity->AddSensorRing(
117 CVector3(0.0f, 0.0f, PROXIMITY_SENSOR_RING_ELEVATION),
118 PROXIMITY_SENSOR_RING_RADIUS,
119 PROXIMITY_SENSOR_RING_START_ANGLE,
120 PROXIMITY_SENSOR_RING_RANGE,
121 24,
122 m_pcEmbodiedEntity->GetOriginAnchor());
123 /* Light sensor equipped entity */
124 m_pcLightSensorEquippedEntity =
126 "light_0");
127 AddComponent(*m_pcLightSensorEquippedEntity);
128 m_pcLightSensorEquippedEntity->AddSensorRing(
129 CVector3(0.0f, 0.0f, PROXIMITY_SENSOR_RING_ELEVATION),
130 PROXIMITY_SENSOR_RING_RADIUS,
131 PROXIMITY_SENSOR_RING_START_ANGLE,
132 PROXIMITY_SENSOR_RING_RANGE,
133 24,
134 m_pcEmbodiedEntity->GetOriginAnchor());
135 /* RAB equipped entity */
136 m_pcRABEquippedEntity = new CRABEquippedEntity(
137 this,
138 "rab_0",
139 un_rab_data_size,
140 f_rab_range,
141 m_pcEmbodiedEntity->GetOriginAnchor(),
142 *m_pcEmbodiedEntity);
143 AddComponent(*m_pcRABEquippedEntity);
144 /* Perspective camera equipped entity */
146 SAnchor& cPerspCamAnchor = m_pcEmbodiedEntity->AddAnchor("perspective_camera",
147 CVector3(0.0, 0.0, 0.0),
148 cPerspCamOrient);
149 m_pcPerspectiveCameraEquippedEntity =
151 "perspective_camera_0",
152 c_perspcam_aperture,
153 f_perspcam_focal_length,
154 f_perspcam_range,
155 640, 480,
156 cPerspCamAnchor);
157 AddComponent(*m_pcPerspectiveCameraEquippedEntity);
158 /* Battery senesor equipped entity */
159 m_pcBatteryEquippedEntity = new CBatteryEquippedEntity(this, "battery_0", str_bat_model);
160 AddComponent(*m_pcBatteryEquippedEntity);
161 /* Controllable entity
162 It must be the last one, for actuators/sensors to link to composing entities correctly */
163 m_pcControllableEntity = new CControllableEntity(this, "controller_0");
164 AddComponent(*m_pcControllableEntity);
165 m_pcControllableEntity->SetController(str_controller_id);
166 /* Update components */
168 }
169 catch(CARGoSException& ex) {
170 THROW_ARGOSEXCEPTION_NESTED("Failed to initialize entity \"" << GetId() << "\".", ex);
171 }
172 }
173
174 /****************************************/
175 /****************************************/
176
178 try {
179 /*
180 * Init parent
181 */
183 /*
184 * Create and init components
185 */
186 /*
187 * Embodied entity
188 * Better to put this first, because many other entities need this one
189 */
190 m_pcEmbodiedEntity = new CEmbodiedEntity(this);
191 AddComponent(*m_pcEmbodiedEntity);
192 m_pcEmbodiedEntity->Init(GetNode(t_tree, "body"));
193 /* Quadrotor entity */
194 m_pcQuadRotorEntity = new CQuadRotorEntity(this, "quadrotor_0");
195 AddComponent(*m_pcQuadRotorEntity);
196 /* LED equipped entity, with LEDs [0-11] and beacon [12] */
197 m_pcLEDEquippedEntity = new CLEDEquippedEntity(this, "leds_0");
198 m_pcLEDEquippedEntity->AddLEDRing(
199 CVector3(0.0f, 0.0f, LED_LOWER_RING_ELEVATION),
200 LED_RING_RADIUS,
201 HALF_LED_ANGLE_SLICE,
202 16,
203 m_pcEmbodiedEntity->GetOriginAnchor());
204 m_pcLEDEquippedEntity->AddLEDRing(
205 CVector3(0.0f, 0.0f, LED_UPPER_RING_ELEVATION),
206 LED_RING_RADIUS,
207 HALF_LED_ANGLE_SLICE,
208 16,
209 m_pcEmbodiedEntity->GetOriginAnchor());
210 CVector3 cLEDPos(LED_RING_RADIUS * 0.7f,
211 0.0f,
212 LED_LOWER_RING_ELEVATION - 0.01f);
213 cLEDPos.RotateZ(3.0f * CRadians::PI_OVER_FOUR);
214 m_pcLEDEquippedEntity->AddLED(
215 cLEDPos,
216 m_pcEmbodiedEntity->GetOriginAnchor());
217 AddComponent(*m_pcLEDEquippedEntity);
218 /* Proximity sensor equipped entity */
219 m_pcProximitySensorEquippedEntity =
221 "proximity_0");
222 AddComponent(*m_pcProximitySensorEquippedEntity);
223 m_pcProximitySensorEquippedEntity->AddSensorRing(
224 CVector3(0.0f, 0.0f, PROXIMITY_SENSOR_RING_ELEVATION),
225 PROXIMITY_SENSOR_RING_RADIUS,
226 PROXIMITY_SENSOR_RING_START_ANGLE,
227 PROXIMITY_SENSOR_RING_RANGE,
228 24,
229 m_pcEmbodiedEntity->GetOriginAnchor());
230 /* Light sensor equipped entity */
231 m_pcLightSensorEquippedEntity =
233 "light_0");
234 AddComponent(*m_pcLightSensorEquippedEntity);
235 m_pcLightSensorEquippedEntity->AddSensorRing(
236 CVector3(0.0f, 0.0f, PROXIMITY_SENSOR_RING_ELEVATION),
237 PROXIMITY_SENSOR_RING_RADIUS,
238 PROXIMITY_SENSOR_RING_START_ANGLE,
239 PROXIMITY_SENSOR_RING_RANGE,
240 24,
241 m_pcEmbodiedEntity->GetOriginAnchor());
242 /* RAB equipped entity */
243 Real fRange = 3.0f;
244 GetNodeAttributeOrDefault(t_tree, "rab_range", fRange, fRange);
245 UInt32 unDataSize = 10;
246 GetNodeAttributeOrDefault(t_tree, "rab_data_size", unDataSize, unDataSize);
247 m_pcRABEquippedEntity = new CRABEquippedEntity(
248 this,
249 "rab_0",
250 unDataSize,
251 fRange,
252 m_pcEmbodiedEntity->GetOriginAnchor(),
253 *m_pcEmbodiedEntity);
254 AddComponent(*m_pcRABEquippedEntity);
255 /* Perspective camera equipped entity */
256 bool bPerspCamFront = true;
257 GetNodeAttributeOrDefault(t_tree, "camera_front", bPerspCamFront, bPerspCamFront);
258 Real fPerspCamFocalLength = 0.035;
259 GetNodeAttributeOrDefault(t_tree, "camera_focal_length", fPerspCamFocalLength, fPerspCamFocalLength);
260 Real fPerspCamRange = 2.0;
261 GetNodeAttributeOrDefault(t_tree, "camera_range", fPerspCamRange, fPerspCamRange);
262 CDegrees cAperture(30.0f);
263 GetNodeAttributeOrDefault(t_tree, "camera_aperture", cAperture, cAperture);
265 SAnchor& cPerspCamAnchor = m_pcEmbodiedEntity->AddAnchor("perspective_camera",
266 CVector3(0.0, 0.0, 0.0),
267 cPerspCamOrient);
268 m_pcPerspectiveCameraEquippedEntity =
270 "perspective_camera_0",
271 ToRadians(cAperture),
272 fPerspCamFocalLength,
273 fPerspCamRange,
274 640, 480,
275 cPerspCamAnchor);
276 AddComponent(*m_pcPerspectiveCameraEquippedEntity);
277 /* Battery equipped entity */
278 m_pcBatteryEquippedEntity = new CBatteryEquippedEntity(this, "battery_0");
279 if(NodeExists(t_tree, "battery"))
280 m_pcBatteryEquippedEntity->Init(GetNode(t_tree, "battery"));
281 AddComponent(*m_pcBatteryEquippedEntity);
282 /* Controllable entity
283 It must be the last one, for actuators/sensors to link to composing entities correctly */
284 m_pcControllableEntity = new CControllableEntity(this);
285 AddComponent(*m_pcControllableEntity);
286 m_pcControllableEntity->Init(GetNode(t_tree, "controller"));
287 /* Update components */
289 }
290 catch(CARGoSException& ex) {
291 THROW_ARGOSEXCEPTION_NESTED("Failed to initialize entity \"" << GetId() << "\".", ex);
292 }
293 }
294
295 /****************************************/
296 /****************************************/
297
299 /* Reset all components */
301 /* Update components */
303 }
304
305 /****************************************/
306 /****************************************/
307
308#define UPDATE(COMPONENT) if(COMPONENT->IsEnabled()) COMPONENT->Update();
309
311 UPDATE(m_pcRABEquippedEntity);
312 UPDATE(m_pcLEDEquippedEntity);
313 UPDATE(m_pcBatteryEquippedEntity);
314 }
315
316 /****************************************/
317 /****************************************/
318
320 "eye-bot",
321 "Carlo Pinciroli [ilpincy@gmail.com]",
322 "1.0",
323 "The eye-bot robot, developed in the Swarmanoid project.",
324 "The eye-bot is a quad-rotor developed in the Swarmanoid Project. It is a\n"
325 "fully autonomous robot with a rich set of sensors and actuators. For more\n"
326 "information, refer to the dedicated web page\n"
327 "(http://www.swarmanoid.org/swarmanoid_hardware.php).\n\n"
328 "REQUIRED XML CONFIGURATION\n\n"
329 " <arena ...>\n"
330 " ...\n"
331 " <eye-bot id=\"eb0\">\n"
332 " <body position=\"0.4,2.3,0.25\" orientation=\"45,0,0\" />\n"
333 " <controller config=\"mycntrl\" />\n"
334 " </eye-bot>\n"
335 " ...\n"
336 " </arena>\n\n"
337 "The 'id' attribute is necessary and must be unique among the entities. If two\n"
338 "entities share the same id, initialization aborts.\n"
339 "The 'body/position' attribute specifies the position of the bottom point of the\n"
340 "eye-bot in the arena. When the robot is untranslated and unrotated, the\n"
341 "bottom point is in the origin and it is defined as the middle point between\n"
342 "the two wheels on the XY plane and the lowest point of the robot on the Z\n"
343 "axis, that is the point where the wheels touch the floor. The attribute values\n"
344 "are in the X,Y,Z order.\n"
345 "The 'body/orientation' attribute specifies the orientation of the eye-bot. All\n"
346 "rotations are performed with respect to the bottom point. The order of the\n"
347 "angles is Z,Y,X, which means that the first number corresponds to the rotation\n"
348 "around the Z axis, the second around Y and the last around X. This reflects\n"
349 "the internal convention used in ARGoS, in which rotations are performed in\n"
350 "that order. Angles are expressed in degrees. When the robot is unrotated, it\n"
351 "is oriented along the X axis.\n"
352 "The 'controller/config' attribute is used to assign a controller to the\n"
353 "eye-bot. The value of the attribute must be set to the id of a previously\n"
354 "defined controller. Controllers are defined in the <controllers> XML subtree.\n\n"
355 "OPTIONAL XML CONFIGURATION\n\n"
356 "You can set the emission range of the range-and-bearing system. By default, a\n"
357 "message sent by an eye-bot can be received up to 3m. By using the 'rab_range'\n"
358 "attribute, you can change it to, i.e., 4m as follows:\n\n"
359 " <arena ...>\n"
360 " ...\n"
361 " <eye-bot id=\"eb0\" rab_range=\"4\">\n"
362 " <body position=\"0.4,2.3,0.25\" orientation=\"45,0,0\" />\n"
363 " <controller config=\"mycntrl\" />\n"
364 " </eye-bot>\n"
365 " ...\n"
366 " </arena>\n\n"
367 "You can also set the data sent at each time step through the range-and-bearing\n"
368 "system. By default, a message sent by a eye-bot is 10 bytes long. By using the\n"
369 "'rab_data_size' attribute, you can change it to, i.e., 20 bytes as follows:\n\n"
370 " <arena ...>\n"
371 " ...\n"
372 " <eye-bot id=\"eb0\" rab_data_size=\"20\">\n"
373 " <body position=\"0.4,2.3,0.25\" orientation=\"45,0,0\" />\n"
374 " <controller config=\"mycntrl\" />\n"
375 " </eye-bot>\n"
376 " ...\n"
377 " </arena>\n\n"
378 "You can also configure the battery of the robot. By default, the battery never\n"
379 "depletes. You can choose among several battery discharge models, such as\n"
380 "- time: the battery depletes by a fixed amount at each time step\n"
381 "- motion: the battery depletes according to how the robot moves\n"
382 "- time_motion: a combination of the above models.\n"
383 "You can define your own models too. Follow the examples in the file\n"
384 "argos3/src/plugins/simulator/entities/battery_equipped_entity.cpp.\n\n"
385 " <arena ...>\n"
386 " ...\n"
387 " <eye-bot id=\"eb0\"\n"
388 " <body position=\"0.4,2.3,0.25\" orientation=\"45,0,0\" />\n"
389 " <controller config=\"mycntrl\" />\n"
390 " <battery model=\"time\" factor=\"1e-5\"/>\n"
391 " </eye-bot>\n"
392 " ...\n"
393 " </arena>\n\n"
394 " <arena ...>\n"
395 " ...\n"
396 " <eye-bot id=\"eb0\"\n"
397 " <body position=\"0.4,2.3,0.25\" orientation=\"45,0,0\" />\n"
398 " <controller config=\"mycntrl\" />\n"
399 " <battery model=\"motion\" pos_factor=\"1e-3\"\n"
400 " orient_factor=\"1e-3\"/>\n"
401 " </eye-bot>\n"
402 " ...\n"
403 " </arena>\n\n"
404 " <arena ...>\n"
405 " ...\n"
406 " <eye-bot id=\"eb0\"\n"
407 " <body position=\"0.4,2.3,0.25\" orientation=\"45,0,0\" />\n"
408 " <controller config=\"mycntrl\" />\n"
409 " <battery model=\"time_motion\" time_factor=\"1e-5\"\n"
410 " pos_factor=\"1e-3\"\n"
411 " orient_factor=\"1e-3\"/>\n"
412 " </eye-bot>\n"
413 " ...\n"
414 " </arena>\n\n"
415 "Finally, you can change the parameters of the camera. You can set its aperture,\n"
416 "focal length, and range with the attributes 'camera_aperture',\n"
417 "'camera_focal_length', and 'camera_range', respectively. The default values are:\n"
418 "30 degrees for aperture, 0.035 for focal length, and 2 meters for range. Check\n"
419 "the following example:\n\n"
420 " <arena ...>\n"
421 " ...\n"
422 " <eye-bot id=\"eb0\"\n"
423 " camera_aperture=\"45\"\n"
424 " camera_focal_length=\"0.07\"\n"
425 " camera_range=\"10\">\n"
426 " <body position=\"0.4,2.3,0.25\" orientation=\"45,0,0\" />\n"
427 " <controller config=\"mycntrl\" />\n"
428 " </eye-bot>\n"
429 " ...\n"
430 " </arena>\n\n"
431 ,
432 "Usable"
433 );
434
435 /****************************************/
436 /****************************************/
437
439
440 /****************************************/
441 /****************************************/
442
443}
#define UPDATE(COMPONENT)
#define ARGOS_PI
To be used when initializing static variables.
Definition angles.h:32
unsigned int UInt32
32-bit unsigned integer.
Definition datatypes.h:97
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_ENTITY(CLASSNAME, LABEL, AUTHOR, VERSION, BRIEF_DESCRIPTION, LONG_DESCRIPTION, STATUS)
Definition entity.h:432
The namespace containing all the ARGoS related code.
Definition ci_actuator.h:12
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.
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.
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.
CRadians ToRadians(const CDegrees &c_degrees)
Converts CDegrees to CRadians.
Definition angles.h:498
REGISTER_STANDARD_SPACE_OPERATIONS_ON_COMPOSABLE(CComposableEntity)
Basic class for an entity that contains other entities.
virtual void Reset()
Resets the state of the entity to whatever it was after Init() or the standalone constructor was call...
void AddComponent(CEntity &c_component)
Adds a component to this composable entity.
An entity that contains a pointer to the user-defined controller.
void SetController(const std::string &str_controller_id)
Creates and assigns a controller with the given id.
virtual void Init(TConfigurationNode &t_tree)
Initializes the state of the entity from the XML configuration tree.
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.
virtual void Init(TConfigurationNode &t_tree)
Initializes the state of the entity from the XML configuration tree.
SAnchor & AddAnchor(const std::string &str_id, const CVector3 &c_rel_position=CVector3(), const CQuaternion &c_rel_orientation=CQuaternion())
Adds an anchor to the embodied entity.
const std::string & GetId() const
Returns the id of this entity.
Definition entity.h:157
virtual void Init(TConfigurationNode &t_tree)
Initializes the state of the entity from the XML configuration tree.
Definition entity.cpp:40
An anchor related to the body of an entity.
The exception that wraps all errors in ARGoS.
It defines the basic type CRadians, used to store an angle value in radians.
Definition angles.h:42
static const CRadians PI_OVER_FOUR
Set to PI / 4.
Definition angles.h:69
static const CRadians PI_OVER_TWO
Set to PI / 2.
Definition angles.h:59
It defines the basic type CDegrees, used to store an angle value in degrees.
Definition angles.h:288
A 3D vector class.
Definition vector3.h:31
static const CVector3 Y
The y axis.
Definition vector3.h:39
CVector3 & RotateZ(const CRadians &c_angle)
Rotates this vector wrt the z axis.
Definition vector3.h:287
virtual void Reset()
Resets the state of the entity to whatever it was after Init() or the standalone constructor was call...
virtual void UpdateComponents()
Calls the Update() method on all the components.
virtual void Init(TConfigurationNode &t_tree)
Initializes the state of the entity from the XML configuration tree.
virtual void Init(TConfigurationNode &t_tree)
Initializes the state of the entity from the XML configuration tree.
A container of CLEDEntity.
void AddLEDRing(const CVector3 &c_center, Real f_radius, const CRadians &c_start_angle, UInt32 un_num_leds, SAnchor &s_anchor, const CColor &c_color=CColor::BLACK)
Adds a ring of LEDs to this entity.
void AddLED(const CVector3 &c_offset, SAnchor &s_anchor, const CColor &c_color=CColor::BLACK)
Adds an LED to this entity.
void AddSensorRing(const CVector3 &c_center, Real f_radius, const CRadians &c_start_angle, Real f_range, UInt32 un_num_sensors, SAnchor &s_anchor)
void AddSensorRing(const CVector3 &c_center, Real f_radius, const CRadians &c_start_angle, Real f_range, UInt32 un_num_sensors, SAnchor &s_anchor)