ARGoS 3
A parallel, multi-engine simulator for swarm robotics
real_robot.cpp
Go to the documentation of this file.
1#include "real_robot.h"
2#include <argos3/core/utility/rate.h>
3#include <argos3/core/utility/logging/argos_log.h>
4#include <argos3/core/control_interface/ci_controller.h>
5#include <signal.h>
6#include <unistd.h>
7
8using namespace argos;
9
10/****************************************/
11/****************************************/
12
14
15/****************************************/
16/****************************************/
17
19 m_pcController(NULL) {
20 /* Set instance */
21 m_pcInstance = this;
22}
23
24/****************************************/
25/****************************************/
26
27void CRealRobot::Init(const std::string& str_conf_fname,
28 const std::string& str_controller_id) {
29 /* Parse the .argos file */
30 m_tConfiguration.LoadFile(str_conf_fname);
31 m_tConfRoot = *m_tConfiguration.FirstChildElement();
32 /*
33 * Install signal handlers
34 */
35 ::signal(SIGINT, Cleanup);
36 ::signal(SIGQUIT, Cleanup);
37 ::signal(SIGABRT, Cleanup);
38 ::signal(SIGTERM, Cleanup);
39 /*
40 * Get the control rate
41 */
42 TConfigurationNode& tFramework = GetNode(m_tConfRoot, "framework");
43 TConfigurationNode& tExperiment = GetNode(tFramework, "experiment");
44 GetNodeAttribute(tExperiment, "ticks_per_second", m_fRate);
45 /*
46 * Parse XML to identify the controller to run
47 */
48 std::string strControllerId, strControllerTag;
49 TConfigurationNode& tControllers = GetNode(m_tConfRoot, "controllers");
50 TConfigurationNodeIterator itControllers;
51 /* Search for the controller tag with the given id */
52 for(itControllers = itControllers.begin(&tControllers);
53 itControllers != itControllers.end() && strControllerTag == "";
54 ++itControllers) {
55 GetNodeAttribute(*itControllers, "id", strControllerId);
56 if(strControllerId == str_controller_id) {
57 strControllerTag = itControllers->Value();
58 m_ptControllerConfRoot = &(*itControllers);
59 }
60 }
61 /* Make sure we found the tag */
62 if(strControllerTag == "") {
63 THROW_ARGOSEXCEPTION("Can't find controller with id \"" << str_controller_id << "\"");
64 }
65 /*
66 * Initialize the robot
67 */
68 LOG << "[INFO] Robot initialization start" << std::endl;
69 InitRobot();
70 LOG << "[INFO] Robot initialization done" << std::endl;
71 /*
72 * Initialize the controller
73 */
74 LOG << "[INFO] Controller type '" << strControllerTag << "', id '" << str_controller_id << "' initialization start" << std::endl;
75#ifdef ARGOS_DYNAMIC_LIBRARY_LOADING
77#else
78 m_pcController = ControllerMaker(strControllerTag);
79#endif
80 /* Set the controller id using the machine hostname */
81 char pchHostname[256];
82 pchHostname[255] = '\0';
83 ::gethostname(pchHostname, 255);
84 m_pcController->SetId(pchHostname);
85 LOG << "[INFO] Controller id set to '" << pchHostname << "'" << std::endl;
86 /* Go through actuators */
87 TConfigurationNode& tActuators = GetNode(*m_ptControllerConfRoot, "actuators");
89 for(itAct = itAct.begin(&tActuators);
90 itAct != itAct.end();
91 ++itAct) {
92 /* itAct->Value() is the name of the current actuator */
93 CCI_Actuator* pcCIAct = MakeActuator(itAct->Value());
94 if(pcCIAct == NULL) {
95 THROW_ARGOSEXCEPTION("Unknown actuator \"" << itAct->Value() << "\"");
96 }
97 pcCIAct->Init(*itAct);
98 m_pcController->AddActuator(itAct->Value(), pcCIAct);
99 }
100 /* Go through sensors */
101 TConfigurationNode& tSensors = GetNode(*m_ptControllerConfRoot, "sensors");
103 for(itSens = itSens.begin(&tSensors);
104 itSens != itSens.end();
105 ++itSens) {
106 /* itSens->Value() is the name of the current sensor */
107 CCI_Sensor* pcCISens = MakeSensor(itSens->Value());
108 if(pcCISens == NULL) {
109 THROW_ARGOSEXCEPTION("Unknown sensor \"" << itSens->Value() << "\"");
110 }
111 pcCISens->Init(*itSens);
112 m_pcController->AddSensor(itSens->Value(), pcCISens);
113 }
114 /* Configure the controller */
116 LOG << "[INFO] Controller type '" << strControllerTag << "', id '" << str_controller_id << "' initialization done" << std::endl;
117}
118
119/****************************************/
120/****************************************/
121
126
127/****************************************/
128/****************************************/
129
133
134/****************************************/
135/****************************************/
136
138 /* Enforce the control rate */
139 CRate cRate(m_fRate);
140 /* Main loop */
141 LOG << "[INFO] Control loop running" << std::endl;
142 /* Save current time */
143 ::timeval tPast, tNow, tDiff;
144 Real fElapsed;
145 ::gettimeofday(&tPast, NULL);
146 while(1) {
147 /* Get elapsed time */
148 ::gettimeofday(&tNow, NULL);
149 timersub(&tNow, &tPast, &tDiff);
150 fElapsed = static_cast<Real>(tDiff.tv_sec * 1000000 + tDiff.tv_usec) / 1e6;
151 tPast = tNow;
152 /* Do useful work */
153 Sense(fElapsed);
154 Control();
155 Act(fElapsed);
156 /* Sleep to enforce control rate */
157 cRate.Sleep();
158 }
159}
160
161/****************************************/
162/****************************************/
163
165 LOG << "[INFO] Stopping controller" << std::endl;
166 if(m_pcInstance != NULL) {
168 delete m_pcInstance;
169 }
170 LOG << "[INFO] All done" << std::endl;
171 exit(0);
172}
173
174/****************************************/
175/****************************************/
float Real
Collects all ARGoS code.
Definition datatypes.h:39
#define THROW_ARGOSEXCEPTION(message)
This macro throws an ARGoS exception with the passed message.
argos::CCI_Controller * ControllerMaker(const std::string &str_label)
Registers a new controller inside ARGoS.
The namespace containing all the ARGoS related code.
Definition ci_actuator.h:12
ticpp::Iterator< ticpp::Element > TConfigurationNodeIterator
The iterator for the ARGoS configuration XML node.
ticpp::Element TConfigurationNode
The ARGoS configuration XML node.
CARGoSLog LOG(std::cout, SLogColor(ARGOS_LOG_ATTRIBUTE_BRIGHT, ARGOS_LOG_COLOR_GREEN))
Definition argos_log.h:179
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.
void GetNodeAttribute(TConfigurationNode &t_node, const std::string &str_attribute, T &t_buffer)
Returns the value of a node's attribute.
The basic interface for all actuators.
Definition ci_actuator.h:34
virtual void Init(TConfigurationNode &t_node)
Initializes the actuator from the XML configuration tree.
Definition ci_actuator.h:54
virtual void Init(TConfigurationNode &t_node)
Initializes the controller.
void AddSensor(const std::string &str_sensor_type, CCI_Sensor *pc_sensor)
Adds an sensor to this controller.
virtual void ControlStep()
Executes a control step.
void SetId(const std::string &str_id)
Sets the id of the robot associated to this controller.
void AddActuator(const std::string &str_actuator_type, CCI_Actuator *pc_actuator)
Adds an actuator to this controller.
The basic interface for all sensors.
Definition ci_sensor.h:34
virtual void Init(TConfigurationNode &t_node)
Initializes the sensor from the XML configuration tree.
Definition ci_sensor.h:54
virtual void Init(const std::string &str_conf_fname, const std::string &str_controller_id)
Initializes the robot and the controller.
virtual void Control()
Execute the robot controller.
virtual ~CRealRobot()
Class destructor.
virtual void Destroy()=0
Put your robot cleanup code here.
CCI_Controller * m_pcController
Definition real_robot.h:79
ticpp::Document m_tConfiguration
Definition real_robot.h:80
TConfigurationNode * m_ptControllerConfRoot
Definition real_robot.h:82
virtual void Act(Real f_elapsed_time)=0
Send data to the actuators.
CRealRobot()
Class constructor.
TConfigurationNode m_tConfRoot
Definition real_robot.h:81
virtual void Execute()
Performs the main loop.
virtual void Sense(Real f_elapsed_time)=0
Collect data from the sensors.
static void Cleanup(int)
Cleanup function called when the controller is stopped.
virtual CCI_Sensor * MakeSensor(const std::string &str_name)=0
Creates a sensor given its name.
virtual CCI_Actuator * MakeActuator(const std::string &str_name)=0
Creates an actuator given its name.
virtual void InitRobot()=0
Put your robot initialization code here.
static CRealRobot * m_pcInstance
Definition real_robot.h:84
static TYPE * New(const std::string &str_label)
Creates a new object of type TYPE
void Sleep()
Sleeps for the appropriate time to complete the period.
Definition rate.cpp:38