simulator.cpp
Go to the documentation of this file.
1 
7 #include "simulator.h"
8 
9 #include <iostream>
10 #include <memory>
11 #include <string>
12 #include <sys/time.h>
13 #include <argos3/core/utility/logging/argos_log.h>
14 #include <argos3/core/utility/profiler/profiler.h>
15 #include <argos3/core/utility/string_utilities.h>
16 #include <argos3/core/utility/plugins/dynamic_loading.h>
17 #include <argos3/core/utility/math/rng.h>
18 #include <argos3/core/simulator/space/space_no_threads.h>
19 #include <argos3/core/simulator/space/space_multi_thread_balance_quantity.h>
20 #include <argos3/core/simulator/space/space_multi_thread_balance_length.h>
21 #include <argos3/core/simulator/visualization/default_visualization.h>
22 #include <argos3/core/simulator/physics_engine/physics_engine.h>
23 #include <argos3/core/simulator/loop_functions.h>
24 #include <argos3/core/simulator/entity/composable_entity.h>
25 #include <argos3/core/simulator/entity/embodied_entity.h>
26 
27 namespace argos {
28 
29  /****************************************/
30  /****************************************/
31 
32  CSimulator::CSimulator() :
33  m_pcVisualization(NULL),
34  m_pcSpace(NULL),
35  m_pcLoopFunctions(NULL),
36  m_unMaxSimulationClock(0),
37  m_bWasRandomSeedSet(false),
38  m_unThreads(0),
39  m_pcProfiler(NULL),
40  m_bHumanReadableProfile(true),
41  m_bRealTimeClock(false),
42  m_bTerminated(false) {}
43 
44  /****************************************/
45  /****************************************/
46 
47  CSimulator::~CSimulator() {
48  if(IsProfiling()) {
49  delete m_pcProfiler;
50  }
51  /* Delete the visualization */
52  if(m_pcVisualization != NULL) delete m_pcVisualization;
53  /* Delete all the media */
54  for(CMedium::TMap::iterator it = m_mapMedia.begin();
55  it != m_mapMedia.end(); ++it) {
56  delete it->second;
57  }
58  m_mapMedia.clear();
59  m_vecMedia.clear();
60  /* Delete all the physics engines */
61  for(CPhysicsEngine::TMap::iterator it = m_mapPhysicsEngines.begin();
62  it != m_mapPhysicsEngines.end(); ++it) {
63  delete it->second;
64  }
65  m_mapPhysicsEngines.clear();
66  m_vecPhysicsEngines.clear();
67  /* Delete the space and the dynamic linking manager */
68  if(m_pcSpace != NULL) {
69  delete m_pcSpace;
70  }
71  /* Get rid of all libraries */
72  CDynamicLoading::UnloadAllLibraries();
73  }
74 
75  /****************************************/
76  /****************************************/
77 
78  CSimulator& CSimulator::GetInstance() {
79  static std::unique_ptr<CSimulator> pcSimulatorInstance(new CSimulator());
80  return *(pcSimulatorInstance.get());
81  }
82 
83  /****************************************/
84  /****************************************/
85 
86  CPhysicsEngine& CSimulator::GetPhysicsEngine(const std::string& str_id) const {
87  CPhysicsEngine::TMap::const_iterator it = m_mapPhysicsEngines.find(str_id);
88  ARGOS_ASSERT(it != m_mapPhysicsEngines.end(), "Physics engine \"" << str_id << "\" not found.")
89  return *(it->second);
90  }
91 
92  /****************************************/
93  /****************************************/
94 
95  TConfigurationNode& CSimulator::GetConfigForController(const std::string& str_id) {
96  TControllerConfigurationMap::iterator it = m_mapControllerConfig.find(str_id);
97  if(it == m_mapControllerConfig.end()) {
98  THROW_ARGOSEXCEPTION("Can't find XML configuration for controller id \"" << str_id << "\"");
99  }
100  return *(it->second);
101  }
102 
103  /****************************************/
104  /****************************************/
105 
106  void CSimulator::Load(ticpp::Document& t_tree) {
107  /* Build configuration tree */
108  m_tConfiguration = t_tree;
109  m_tConfigurationRoot = *m_tConfiguration.FirstChildElement();
110  /* Init the experiment */
111  Init();
112  LOG.Flush();
113  LOGERR.Flush();
114  }
115 
116  /****************************************/
117  /****************************************/
118 
119  void CSimulator::LoadExperiment() {
120  /* Build configuration tree */
121  m_tConfiguration.LoadFile(m_strExperimentConfigFileName);
122  m_tConfigurationRoot = *m_tConfiguration.FirstChildElement();
123  /* Init the experiment */
124  Init();
125  LOG.Flush();
126  LOGERR.Flush();
127  }
128 
129  /****************************************/
130  /****************************************/
131 
132  void CSimulator::Init() {
133  /* General configuration */
134  InitFramework(GetNode(m_tConfigurationRoot, "framework"));
135  /* Initialize controllers */
136  InitControllers(GetNode(m_tConfigurationRoot, "controllers"));
137  /* Create loop functions */
138  if(NodeExists(m_tConfigurationRoot, "loop_functions")) {
139  /* User specified a loop_functions section in the XML */
140  InitLoopFunctions(GetNode(m_tConfigurationRoot, "loop_functions"));
141  }
142  else {
143  /* No loop_functions in the XML */
144  m_pcLoopFunctions = new CLoopFunctions;
145  }
146  /* Physics engines */
147  InitPhysics(GetNode(m_tConfigurationRoot, "physics_engines"));
148  /* Media */
149  InitMedia(GetNode(m_tConfigurationRoot, "media"));
150  /* Space */
151  InitSpace(GetNode(m_tConfigurationRoot, "arena"));
152  /* Call user init function */
153  if(NodeExists(m_tConfigurationRoot, "loop_functions")) {
154  m_pcLoopFunctions->Init(GetNode(m_tConfigurationRoot, "loop_functions"));
155  }
156  /* Physics engines */
157  InitPhysics2();
158  /* Media */
159  InitMedia2();
160  /* Initialise visualization */
161  TConfigurationNodeIterator itVisualization;
162  if(NodeExists(m_tConfigurationRoot, "visualization") &&
163  ((itVisualization = itVisualization.begin(&GetNode(m_tConfigurationRoot, "visualization"))) != itVisualization.end())) {
164  InitVisualization(GetNode(m_tConfigurationRoot, "visualization"));
165  }
166  else {
167  LOG << "[INFO] No visualization selected." << std::endl;
168  m_pcVisualization = new CDefaultVisualization();
169  }
170  /* Start profiling, if needed */
171  if(IsProfiling()) {
172  m_pcProfiler->Start();
173  }
174  }
175 
176  /****************************************/
177  /****************************************/
178 
179  void CSimulator::Reset() {
180  /* Reset terminated flag */
181  m_bTerminated = false;
182  /* if random seed is 0 or is not specified, init with the current timeval */
183  if(m_bWasRandomSeedSet) {
184  CRandom::SetSeedOf("argos", m_unRandomSeed);
185  }
186  else {
187  /* Prepare the default value based on the current clock time */
188  struct timeval sTimeValue;
189  ::gettimeofday(&sTimeValue, NULL);
190  UInt32 unSeed = static_cast<UInt32>(sTimeValue.tv_usec);
191  CRandom::SetSeedOf("argos", unSeed);
192  m_unRandomSeed = unSeed;
193  LOG << "[INFO] Using random seed = " << m_unRandomSeed << std::endl;
194  }
195  CRandom::GetCategory("argos").ResetRNGs();
196  /* Reset the space */
197  m_pcSpace->Reset();
198  /* Reset the media */
199  for(CMedium::TMap::iterator it = m_mapMedia.begin();
200  it != m_mapMedia.end(); ++it) {
201  it->second->Reset();
202  }
203  /* Reset the physics engines */
204  for(CPhysicsEngine::TMap::iterator it = m_mapPhysicsEngines.begin();
205  it != m_mapPhysicsEngines.end(); ++it) {
206  it->second->Reset();
207  }
208  /* Reset the loop functions */
209  m_pcLoopFunctions->Reset();
210  LOG.Flush();
211  LOGERR.Flush();
212  }
213 
214  /****************************************/
215  /****************************************/
216 
217  void CSimulator::Destroy() {
218  /* Call user destroy function */
219  if (m_pcLoopFunctions != NULL) {
220  m_pcLoopFunctions->Destroy();
221  delete m_pcLoopFunctions;
222  m_pcLoopFunctions = NULL;
223  }
224  /* Destroy the visualization */
225  if(m_pcVisualization != NULL) {
226  m_pcVisualization->Destroy();
227  }
228  /* Destroy simulated space */
229  if(m_pcSpace != NULL) {
230  m_pcSpace->Destroy();
231  }
232  /* Destroy media */
233  for(CMedium::TMap::iterator it = m_mapMedia.begin();
234  it != m_mapMedia.end(); ++it) {
235  it->second->Destroy();
236  delete it->second;
237  }
238  m_mapMedia.clear();
239  m_vecMedia.clear();
240  /* Destroy physics engines */
241  for(CPhysicsEngine::TMap::iterator it = m_mapPhysicsEngines.begin();
242  it != m_mapPhysicsEngines.end(); ++it) {
243  it->second->Destroy();
244  delete it->second;
245  }
246  m_mapPhysicsEngines.clear();
247  m_vecPhysicsEngines.clear();
248  /* Get rid of ARGoS category */
249  if(CRandom::ExistsCategory("argos")) {
250  CRandom::RemoveCategory("argos");
251  }
252  /* Free up factory data */
261  /* Stop profiling and flush the data */
262  if(IsProfiling()) {
263  m_pcProfiler->Stop();
264  m_pcProfiler->Flush(m_bHumanReadableProfile);
265  }
266  LOG.Flush();
267  LOGERR.Flush();
268  }
269 
270  /****************************************/
271  /****************************************/
272 
273  void CSimulator::Execute() {
274  m_pcVisualization->Execute();
275  }
276 
277  /****************************************/
278  /****************************************/
279 
280  void CSimulator::UpdateSpace() {
281  /* Update the space */
282  m_pcSpace->Update();
283  }
284 
285  /****************************************/
286  /****************************************/
287 
288  bool CSimulator::IsExperimentFinished() const {
289  /* Check if the simulation must be terminated */
290  if(m_bTerminated) {
291  return true;
292  }
293  /* Check simulation clock */
294  if (m_unMaxSimulationClock > 0 &&
295  m_pcSpace->GetSimulationClock() >= m_unMaxSimulationClock) {
296  return true;
297  }
298  /* Call loop function */
299  return m_pcLoopFunctions->IsExperimentFinished();
300  }
301 
302  /****************************************/
303  /****************************************/
304 
305  void CSimulator::InitFramework(TConfigurationNode& t_tree) {
306  try {
307  /* Parse the 'system' node */
308  if(NodeExists(t_tree, "system")) {
309  TConfigurationNode tSystem;
310  tSystem = GetNode(t_tree, "system");
311  GetNodeAttributeOrDefault(tSystem, "threads", m_unThreads, m_unThreads);
312  if(m_unThreads == 0) {
313  LOG << "[INFO] Not using threads" << std::endl;
314  m_pcSpace = new CSpaceNoThreads();
315  }
316  else {
317  LOG << "[INFO] Using " << m_unThreads << " parallel threads" << std::endl;
318  std::string strThreadingMethod = "balance_quantity";
319  GetNodeAttributeOrDefault(tSystem, "method", strThreadingMethod, strThreadingMethod);
320  if(strThreadingMethod == "balance_quantity") {
321  LOG << "[INFO] Chosen method \"balance_quantity\": threads will be assigned the same"
322  << std::endl
323  << "[INFO] number of tasks, independently of the task length."
324  << std::endl;
325  m_pcSpace = new CSpaceMultiThreadBalanceQuantity();
326  }
327  else if(strThreadingMethod == "balance_length") {
328  LOG << "[INFO] Chosen method \"balance_length\": threads will be assigned different"
329  << std::endl
330  << "[INFO] numbers of tasks, depending on the task length."
331  << std::endl;
332  m_pcSpace = new CSpaceMultiThreadBalanceLength();
333  }
334  else {
335  THROW_ARGOSEXCEPTION("Error parsing the <system> tag. Unknown threading method \"" << strThreadingMethod << "\". Available methods: \"balance_quantity\" and \"balance_length\".");
336  }
337  }
338  }
339  else {
340  LOG << "[INFO] Not using threads" << std::endl;
341  m_pcSpace = new CSpaceNoThreads();
342  }
343  /* Get 'experiment' node */
344  TConfigurationNode tExperiment;
345  tExperiment = GetNode(t_tree, "experiment");
346  /* Parse random seed */
347  /* Buffer to hold the random seed */
348  if(!m_bWasRandomSeedSet)
349  GetNodeAttributeOrDefault(tExperiment,
350  "random_seed",
351  m_unRandomSeed,
352  static_cast<UInt32>(0));
353  /* if random seed is 0 or is not specified, init with the current timeval */
354  if(m_unRandomSeed != 0) {
355  CRandom::CreateCategory("argos", m_unRandomSeed);
356  LOG << "[INFO] Using random seed = " << m_unRandomSeed << std::endl;
357  m_bWasRandomSeedSet = true;
358  }
359  else {
360  /* Prepare the default value based on the current clock time */
361  m_bWasRandomSeedSet = false;
362  struct timeval sTimeValue;
363  ::gettimeofday(&sTimeValue, NULL);
364  UInt32 unSeed = static_cast<UInt32>(sTimeValue.tv_usec);
365  m_unRandomSeed = unSeed;
366  CRandom::CreateCategory("argos", unSeed);
367  LOG << "[INFO] Using random seed = " << unSeed << std::endl;
368  }
369  m_pcRNG = CRandom::CreateRNG("argos");
370  /* Set the simulation clock tick length */
371  UInt32 unTicksPerSec;
372  GetNodeAttribute(tExperiment,
373  "ticks_per_second",
374  unTicksPerSec);
375  CPhysicsEngine::SetSimulationClockTick(1.0 / static_cast<Real>(unTicksPerSec));
376  /* Set the maximum simulation duration (in seconds) */
377  Real fExpLength;
378  GetNodeAttributeOrDefault<Real>(tExperiment,
379  "length",
380  fExpLength,
381  0.0f);
382  m_unMaxSimulationClock = fExpLength * unTicksPerSec;
383  LOG << "[INFO] Total experiment length in clock ticks = "
384  << (m_unMaxSimulationClock ? ToString(m_unMaxSimulationClock) : "unlimited")
385  << std::endl;
386  /* Check for the 'real_time' attribute */
387  GetNodeAttributeOrDefault(tExperiment, "real_time", m_bRealTimeClock, m_bRealTimeClock);
388  if(m_bRealTimeClock) {
389  LOG << "[INFO] Using the real-time clock." << std::endl;
390  }
391  /* Get the profiling tag, if present */
392  if(NodeExists(t_tree, "profiling")) {
393  TConfigurationNode& tProfiling = GetNode(t_tree, "profiling");
394  std::string strFile;
395  GetNodeAttribute(tProfiling, "file", strFile);
396  std::string strFormat;
397  GetNodeAttribute(tProfiling, "format", strFormat);
398  if(strFormat == "human_readable") {
399  m_bHumanReadableProfile = true;
400  }
401  else if(strFormat == "table") {
402  m_bHumanReadableProfile = false;
403  }
404  else {
405  THROW_ARGOSEXCEPTION("Unrecognized profile format \"" << strFormat << "\". Accepted values are \"human_readable\" and \"table\".");
406  }
407  bool bTrunc = true;
408  GetNodeAttributeOrDefault(tProfiling, "truncate_file", bTrunc, bTrunc);
409  m_pcProfiler = new CProfiler(strFile, bTrunc);
410  }
411  }
412  catch(CARGoSException& ex) {
413  THROW_ARGOSEXCEPTION_NESTED("Failed to initialize the simulator. Parse error inside the <framework> tag.", ex);
414  }
415  }
416 
417  /****************************************/
418  /****************************************/
419 
420  void CSimulator::InitLoopFunctions(TConfigurationNode& t_tree) {
421  try {
422  std::string strLibrary, strLabel;
423  GetNodeAttributeOrDefault(t_tree, "library", strLibrary, strLibrary);
424  GetNodeAttribute(t_tree, "label", strLabel);
425  if(! strLibrary.empty()) {
426  CDynamicLoading::LoadLibrary(strLibrary);
427  }
428  m_pcLoopFunctions = CFactory<CLoopFunctions>::New(strLabel);
429  }
430  catch(CARGoSException& ex) {
431  THROW_ARGOSEXCEPTION_NESTED("Error initializing loop functions", ex);
432  }
433  }
434 
435  /****************************************/
436  /****************************************/
437 
438  void CSimulator::InitControllers(TConfigurationNode& t_tree) {
439  /*
440  * Go through controllers, loading the library of each of them
441  * and storing type, id and XML tree of each of them for later use
442  */
443  if(! t_tree.NoChildren()) {
444  try {
445  std::string strLibrary;
446  std::string strId;
448  for(it = it.begin(&t_tree);
449  it != it.end(); ++it) {
450  /* Get controller id */
451  try {
452  GetNodeAttribute(*it, "id", strId);
453  }
454  catch(CARGoSException& ex) {
455  std::string strValue;
456  it->GetValue(&strValue);
457  THROW_ARGOSEXCEPTION_NESTED("Controller type \"" << strValue << "\" has no assigned id.", ex);
458  }
459  /* Bomb out if id is already in map */
460  if(m_mapControllerConfig.find(strId) != m_mapControllerConfig.end()) {
461  THROW_ARGOSEXCEPTION("Controller id \"" << strId << "\" duplicated");
462  }
463  /* Optionally, process "library" attribute if present */
464  if(NodeAttributeExists(*it, "library")) {
465  /* Get library name */
466  GetNodeAttribute(*it, "library", strLibrary);
467  /* Load library */
468  CDynamicLoading::LoadLibrary(strLibrary);
469  }
470  /* Store XML info in map by id */
471  m_mapControllerConfig.insert(std::pair<std::string, TConfigurationNode*>(strId, &(*it)));
472  }
473  }
474  catch(CARGoSException& ex) {
475  THROW_ARGOSEXCEPTION_NESTED("Error initializing controllers", ex);
476  }
477  }
478  }
479 
480  /****************************************/
481  /****************************************/
482 
483  void CSimulator::InitSpace(TConfigurationNode& t_tree) {
484  try {
485  m_pcSpace->Init(t_tree);
486  }
487  catch(CARGoSException& ex) {
488  THROW_ARGOSEXCEPTION_NESTED("Failed to initialize the space.", ex);
489  }
490  }
491 
492  /****************************************/
493  /****************************************/
494 
495  void CSimulator::InitPhysics(TConfigurationNode& t_tree) {
496  try {
497  /* Cycle through the physics engines */
498  TConfigurationNodeIterator itEngines;
499  for(itEngines = itEngines.begin(&t_tree);
500  itEngines != itEngines.end();
501  ++itEngines) {
502  /* Create the physics engine */
503  CPhysicsEngine* pcEngine = CFactory<CPhysicsEngine>::New(itEngines->Value());
504  try {
505  /* Initialize the engine */
506  pcEngine->Init(*itEngines);
507  /* Check that an engine with that ID does not exist yet */
508  if(m_mapPhysicsEngines.find(pcEngine->GetId()) == m_mapPhysicsEngines.end()) {
509  /* Add it to the lists */
510  m_mapPhysicsEngines[pcEngine->GetId()] = pcEngine;
511  m_vecPhysicsEngines.push_back(pcEngine);
512  }
513  else {
514  /* Duplicate id -> error */
515  THROW_ARGOSEXCEPTION("A physics engine with id \"" << pcEngine->GetId() << "\" exists already. The ids must be unique!");
516  }
517  }
518  catch(CARGoSException& ex) {
519  /* Error while executing engine init, destroy what done to prevent memory leaks */
520  pcEngine->Destroy();
521  delete pcEngine;
522  THROW_ARGOSEXCEPTION_NESTED("Error initializing physics engine type \"" << itEngines->Value() << "\"", ex);
523  }
524  }
525  }
526  catch(CARGoSException& ex) {
527  THROW_ARGOSEXCEPTION_NESTED("Failed to initialize the physics engines. Parse error in the <physics_engines> subtree.", ex);
528  }
529  }
530 
531  /****************************************/
532  /****************************************/
533 
534  void CSimulator::InitPhysics2() {
535  try {
536  /* Cycle through the physics engines */
537  CPhysicsEngine::TMap::iterator it;
538  for(it = m_mapPhysicsEngines.begin(); it != m_mapPhysicsEngines.end(); ++it) {
539  CPhysicsEngine& cPhysicsEngine = *(it->second);
540  try {
541  /* Initialize the physicsengine */
542  cPhysicsEngine.PostSpaceInit();
543  }
544  catch(CARGoSException& ex) {
545  /* Error while executing physicsengine post space init, destroy what done to prevent memory leaks */
546  std::ostringstream ossMsg;
547  ossMsg << "Error executing post-space initialization of physics engine \"" << cPhysicsEngine.GetId() << "\"";
548  cPhysicsEngine.Destroy();
549  THROW_ARGOSEXCEPTION_NESTED(ossMsg.str(), ex);
550  }
551  }
552  }
553  catch(CARGoSException& ex) {
554  THROW_ARGOSEXCEPTION_NESTED("Failed to initialize the physics engines. Parse error in the <physics_engines> subtree.", ex);
555  }
556  }
557 
558  /****************************************/
559  /****************************************/
560 
561  void CSimulator::InitMedia(TConfigurationNode& t_tree) {
562  try {
563  /* Cycle through the media */
565  for(itMedia = itMedia.begin(&t_tree);
566  itMedia != itMedia.end();
567  ++itMedia) {
568  /* Create the medium */
569  CMedium* pcMedium = CFactory<CMedium>::New(itMedia->Value());
570  try {
571  /* Initialize the medium */
572  pcMedium->Init(*itMedia);
573  /* Check that an medium with that ID does not exist yet */
574  if(m_mapMedia.find(pcMedium->GetId()) == m_mapMedia.end()) {
575  /* Add it to the lists */
576  m_mapMedia[pcMedium->GetId()] = pcMedium;
577  m_vecMedia.push_back(pcMedium);
578  }
579  else {
580  /* Duplicate id -> error */
581  THROW_ARGOSEXCEPTION("A medium with id \"" << pcMedium->GetId() << "\" exists already. The ids must be unique!");
582  }
583  }
584  catch(CARGoSException& ex) {
585  /* Error while executing medium init, destroy what done to prevent memory leaks */
586  pcMedium->Destroy();
587  delete pcMedium;
588  THROW_ARGOSEXCEPTION_NESTED("Error initializing medium type \"" << itMedia->Value() << "\"", ex);
589  }
590  }
591  }
592  catch(CARGoSException& ex) {
593  THROW_ARGOSEXCEPTION_NESTED("Failed to initialize the media. Parse error in the <media> subtree.", ex);
594  }
595  }
596 
597  /****************************************/
598  /****************************************/
599 
600  void CSimulator::InitMedia2() {
601  try {
602  /* Cycle through the media */
603  CMedium::TMap::iterator it;
604  for(it = m_mapMedia.begin(); it != m_mapMedia.end(); ++it) {
605  CMedium& cMedium = *(it->second);
606  try {
607  /* Initialize the medium */
608  cMedium.PostSpaceInit();
609  }
610  catch(CARGoSException& ex) {
611  /* Error while executing medium post space init, destroy what done to prevent memory leaks */
612  std::ostringstream ossMsg;
613  ossMsg << "Error executing post-space initialization of medium \"" << cMedium.GetId() << "\"";
614  cMedium.Destroy();
615  THROW_ARGOSEXCEPTION_NESTED(ossMsg.str(), ex);
616  }
617  }
618  }
619  catch(CARGoSException& ex) {
620  THROW_ARGOSEXCEPTION_NESTED("Failed to initialize the media. Parse error in the <media> subtree.", ex);
621  }
622  }
623 
624  /****************************************/
625  /****************************************/
626 
627  void CSimulator::InitVisualization(TConfigurationNode& t_tree) {
628  try {
629  /* Consider only the first visualization */
630  TConfigurationNodeIterator itVisualization;
631  itVisualization = itVisualization.begin(&t_tree);
632  /* Create the visualization */
633  m_pcVisualization = CFactory<CVisualization>::New(itVisualization->Value());
634  /* Initialize the visualization */
635  m_pcVisualization->Init(*itVisualization);
636  }
637  catch(CARGoSException& ex) {
638  THROW_ARGOSEXCEPTION_NESTED("Failed to initialize the visualization. Parse error in the <visualization> subtree.", ex);
639  }
640  }
641 
642  /****************************************/
643  /****************************************/
644 
645 }
A set of hook functions to customize an experimental run.
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.
float Real
Collects all ARGoS code.
Definition: datatypes.h:39
CARGoSLog LOG(std::cout, SLogColor(ARGOS_LOG_ATTRIBUTE_BRIGHT, ARGOS_LOG_COLOR_GREEN))
Definition: argos_log.h:179
#define THROW_ARGOSEXCEPTION(message)
This macro throws an ARGoS exception with the passed message.
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.
ticpp::Element TConfigurationNode
The ARGoS configuration XML node.
#define THROW_ARGOSEXCEPTION_NESTED(message, nested)
This macro throws an ARGoS exception with the passed message and nesting the passed exception...
STL namespace.
Basic factory template.
Definition: factory.h:59
#define ARGOS_ASSERT(condition, message)
When code is compiled in debug, this macro throws an ARGoS exception with the passed message if the s...
unsigned int UInt32
32-bit unsigned integer.
Definition: datatypes.h:97
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.
bool NodeAttributeExists(TConfigurationNode &t_node, const std::string &str_attribute)
Returns true if the specified attribute of a node exists.
CARGoSLog LOGERR(std::cerr, SLogColor(ARGOS_LOG_ATTRIBUTE_BRIGHT, ARGOS_LOG_COLOR_RED))
Definition: argos_log.h:180
ticpp::Iterator< ticpp::Element > TConfigurationNodeIterator
The iterator for the ARGoS configuration XML node.
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.
The namespace containing all the ARGoS related code.
Definition: ci_actuator.h:12
The core class of ARGOS.
Definition: simulator.h:62