ScriptHost.cpp
Go to the documentation of this file.
00001 /*
00002  * ScriptHost.cpp
00003  *
00004  *  Created on: Oct 27, 2013
00005  *      Author: blackpc
00006  */
00007 
00008 #include <scriptable_monitor/ScriptHost.h>
00009 
00010 ScriptHost::ScriptHost()
00011 {
00012         _executionInterval = 0.1;
00013         RosTopicListener::start();
00014 }
00015 
00016 ScriptHost::~ScriptHost()
00017 {
00018         stop();
00019         RosTopicListener::stop();
00020 }
00021 
00022 AddScriptResponse ScriptHost::addScript(string sourceCode)
00023 {
00024         lock_recursive(_scriptsMutex);
00025         AddScriptResponse response;
00026         response.message = "";
00027 
00028         set<string> internalFunctions;
00029         foreach (string functionName, InternalFunctionsManager::getFunctionNames()) {
00030                 internalFunctions.insert(functionName);
00031         }
00032 
00036         PredicatesScript predicateScript(sourceCode, internalFunctions);
00037         if (predicateScript.getName() == "") {
00038                 cerr << "[e] Unnamed script provided, cannot add to ScriptHost" << endl;
00039                 response.message = "[e] Unnamed script provided, cannot add to ScriptHost";
00040                 response.success = false;
00041                 return response;
00042         }
00043 
00044         if (scriptExists(predicateScript.getName())) {
00045                 cerr << "[e] Script with the same name already exists" << endl;
00046                 response.message = "[e] Script with the same name already exists";
00047                 response.success = false;
00048                 return response;
00049         }
00050 
00054         PythonScript* pythonScript = new PythonScript(predicateScript.getPythonScript());
00055         bool validScript = prepareScript(*pythonScript);
00056 
00057         if (validScript)
00058                 _scripts.insert(boost::shared_ptr<PythonScript>(pythonScript));
00059         else {
00060                 cerr << "[e] Invalid script" << endl;
00061                 response.message = "[e] Invalid script";
00062                 response.success = false;
00063                 return response;
00064         }
00065 
00069         foreach (string topicName, pythonScript->getUsedTopics()) {
00070                 RosTopicListener::addTopic(topicName);
00071         }
00072 
00073         cout << "[+] Script added [" << pythonScript->getName() << "]" << endl;
00074         response.message = "[+] Script added";
00075         response.success = true;
00076         return response;
00077 }
00078 
00079 bool ScriptHost::prepareScript(PythonScript& script)
00080 {
00081         CompilationResult result = _executer.compile(script);
00082         if (!result.success) {
00083                 cerr << "[e] Compilation of script '" << script.getName() << "' failed" << endl;
00084                 cerr << "[e] Message: " << result.message << endl;
00085                 return false;
00086         }
00087 
00091         _executer.simulate(script);
00092 
00093         return true;
00094 }
00095 
00096 void ScriptHost::run()
00097 {
00098         while (!_workThread->interruption_requested()) {
00099 
00100                 {
00101                         lock_recursive(_scriptsMutex);
00102                         foreach (PythonScriptPtr script, _scripts) {
00103 
00104                                 if (!isExecutionTime(script))
00105                                         continue;
00106 
00107                                 if (!hasAllTopicValues(script))
00108                                         continue;
00109 
00110 //                              cout << "[i] Time to execute '" << script->getName() << "'" << endl;
00111                                 _executer.execute(*script, RosTopicListener::getTopicsValues());
00112                                 script->updateExecutionTime();
00113 
00114 //                              cout << "[i] Validations: " << (script->isValidationFailed() ? "FAILED [" + script->getFailedValidation() + "]" : "PASSED") << endl;
00115 
00116                                 addDiagnosticStatus(script);
00117 
00118                         }
00119                 }
00120 
00121                 boost::this_thread::sleep(boost::posix_time::milliseconds(1000.0 * _executionInterval));
00122         }
00123 }
00124 
00125 void ScriptHost::start()
00126 {
00127         RosTopicListener::start();
00128 
00129         if (!_workThread)
00130                 _workThread = boost::shared_ptr<boost::thread>(
00131                                 new boost::thread(boost::bind(&ScriptHost::run, this)));
00132 }
00133 
00134 void ScriptHost::stop()
00135 {
00136         ROS_INFO("Stopping ScriptHost...");
00137         _workThread->interrupt();
00138         _workThread->join();
00139 }
00140 
00141 bool ScriptHost::isExecutionTime(PythonScriptPtr script)
00142 {
00143         boost::posix_time::ptime nowTime = boost::posix_time::microsec_clock::local_time();
00144         boost::posix_time::ptime nextExecutionTime
00145                 = script->getExecutionTime() + boost::posix_time::time_duration(boost::posix_time::milliseconds(1000.0 * script->getInterval()));
00146 
00147         return nowTime > nextExecutionTime;
00148 }
00149 
00150 void ScriptHost::deleteScript(string scriptName)
00151 {
00152         lock_recursive(_scriptsMutex);
00153 
00154         PythonScriptPtr script = getScript(scriptName);
00155 
00156         if (!scriptExists(scriptName))
00157                 return;
00158 
00159         _scripts.erase(script);
00160 }
00161 
00162 void ScriptHost::addDiagnosticStatus(PythonScriptPtr script)
00163 {
00164         lock_recursive(_statusesMutex);
00165 
00166         DiagnosticStatusPtr status(new diagnostic_msgs::DiagnosticStatus());
00167 
00168         status->name = script->getName();
00169         status->hardware_id = script->getParameter("hardware_id");
00170 
00171         if (script->isValidationFailed()) {
00172                 status->level = (int8_t)script->getFailType();
00173         }
00174         else
00175                 status->level = diagnostic_msgs::DiagnosticStatus::OK;
00176 
00177         status->message = script->isValidationFailed() ? "Validation failed: " + script->getFailedValidation() : "Fine";;
00178 
00179         _diagnosticStatuses.push_back(status);
00180 }
00181 
00182 vector<DiagnosticStatusPtr> ScriptHost::getDiagnosticStatusesAndClear()
00183 {
00184         lock_recursive(_statusesMutex);
00185 
00186         vector<DiagnosticStatusPtr> statuses = _diagnosticStatuses;
00187         _diagnosticStatuses.clear();
00188         return statuses;
00189 }
00190 
00191 set<PythonScriptPtr> ScriptHost::getScripts()
00192 {
00193         lock_recursive(_scriptsMutex);
00194         return _scripts;
00195 }
00196 
00197 PythonScriptPtr ScriptHost::getScript(string scriptName)
00198 {
00199         lock_recursive(_scriptsMutex);
00200 
00201         for(std::set<PythonScriptPtr>::iterator it = _scripts.begin(); it != _scripts.end(); it++) {
00202                 if ((*it)->getName() == scriptName)
00203                         return (*it);
00204         }
00205 
00206         return PythonScriptPtr();
00207 }
00208 
00209 bool ScriptHost::hasAllTopicValues(PythonScriptPtr script)
00210 {
00211         foreach(string topicName, script->getUsedTopics()) {
00212                 if (!RosTopicListener::hasTopicValue(topicName))
00213                         return false;
00214         }
00215 
00216         return true;
00217 }
00218 
00219 bool ScriptHost::scriptExists(string scriptName)
00220 {
00221         lock_recursive(_scriptsMutex);
00222         return !(!getScript(scriptName));
00223 }


scriptable_monitor
Author(s):
autogenerated on Wed Aug 26 2015 16:21:30