23 #include "exec_thread.h"
25 #include <core/exceptions/software.h>
26 #include <core/exceptions/system.h>
27 #include <core/threading/mutex.h>
28 #include <logging/component.h>
29 #ifdef SKILLER_TIMETRACKING
30 # include <utils/time/tracker.h>
33 #include <lua/context.h>
34 #include <lua/interface_importer.h>
36 #include <interfaces/SkillerInterface.h>
37 #include <interfaces/SkillerDebugInterface.h>
46 using namespace fawkes;
58 :
Thread(
"SkillerExecutionThread",
Thread::OPMODE_WAITFORWAKEUP),
62 __continuous_run =
false;
63 __continuous_reset =
false;
64 __error_written =
false;
80 SkillerExecutionThread::init_failure_cleanup()
94 "Fawkes is no longer in a clean state. Restart!");
102 __last_exclusive_controller = 0;
103 __reader_just_left =
false;
104 __continuous_run =
false;
105 __continuous_reset =
false;
106 __skdbg_what =
"ACTIVE";
107 __skdbg_graphdir =
"TB";
108 __skdbg_graphcolored =
true;
110 __sksf_pushed =
false;
116 e.
append(
"Insufficient configuration for Skiller");
120 logger->
log_debug(
"SkillerExecutionThread",
"Skill space: %s", __cfg_skillspace.c_str());
129 std::string reading_prefix =
"/skiller/interfaces/" + __cfg_skillspace +
"/reading/";
130 std::string writing_prefix =
"/skiller/interfaces/" + __cfg_skillspace +
"/writing/";
137 if (__cfg_watch_files) {
138 __lua->setup_fam(
true,
false);
147 __lua->add_package_dir(LUADIR);
148 __lua->add_cpackage_dir(LUALIBDIR);
150 __lua->add_package(
"fawkesutils");
151 __lua->add_package(
"fawkesconfig");
152 __lua->add_package(
"fawkeslogging");
153 __lua->add_package(
"fawkesinterface");
154 __lua->add_package(
"fawkesgeometry");
156 __lua->add_package(
"fawkestf");
159 __lua->set_string(
"SKILLSPACE", __cfg_skillspace.c_str());
160 __lua->set_usertype(
"config",
config,
"Configuration",
"fawkes");
161 __lua->set_usertype(
"logger", __clog,
"ComponentLogger",
"fawkes");
162 __lua->set_usertype(
"clock",
clock,
"Clock",
"fawkes");
164 __lua->set_usertype(
"tf", tf_listener,
"Transformer",
"fawkes::tf");
169 __lua->set_start_script(LUADIR
"/skiller/start.lua");
172 __skiller_if->
set_status(SkillerInterface::S_INACTIVE);
173 __skiller_if->
write();
175 __skdbg_if->set_graph(
"");
176 __skdbg_if->set_graph_fsm(
"ACTIVE");
179 init_failure_cleanup();
187 #ifdef SKILLER_TIMETRACKING
189 __ttc_total = __tt->add_class(
"Total");
190 __ttc_msgproc = __tt->add_class(
"Message Processing");
191 __ttc_luaprep = __tt->add_class(
"Lua Preparation");
192 __ttc_luaexec = __tt->add_class(
"Lua Execution");
193 __ttc_publish = __tt->add_class(
"Publishing");
202 #ifdef SKILLER_TIMETRACKING
218 unsigned int instance_serial)
throw()
220 if ( instance_serial == __skiller_if->exclusive_controller() ) {
221 logger->
log_debug(
"SkillerExecutionThread",
"Controlling interface instance was closed, "
222 "revoking exclusive control");
224 __last_exclusive_controller = instance_serial;
225 __reader_just_left =
true;
227 __skiller_if->set_exclusive_controller(0);
228 __skiller_if->write();
239 SkillerExecutionThread::publish_skill_status(std::string &curss)
242 LUA_INTEGER
running = 0,
final = 0, failed = 0;
252 __skiller_if->
set_status(SkillerInterface::S_INACTIVE);
267 throw LuaRuntimeException(
"C++:publish_skill_status",
"skillenv.get_status is not a function");
272 new_status = SkillerInterface::S_FAILED;
273 }
else if ( (
final > 0) && (running == 0) ) {
275 new_status = SkillerInterface::S_FINAL;
276 }
else if ( running > 0 ) {
278 new_status = SkillerInterface::S_RUNNING;
282 new_status = SkillerInterface::S_INACTIVE;
286 if ( (old_status != new_status) ||
301 if ( ! __error_written && (new_status == SkillerInterface::S_FAILED) ) {
303 __error_written = __continuous_run;
304 }
else if (new_status == SkillerInterface::S_RUNNING ||
305 new_status == SkillerInterface::S_FINAL) {
307 __error_written =
false;
310 __skiller_if->
write();
314 logger->
log_error(
"SkillerExecutionThread",
"Failed to retrieve skill status");
317 __skiller_if->
set_status(SkillerInterface::S_FAILED);
319 logger->
log_error(
"SkillerExecutionThread",
"Failed to set FAILED as skill "
320 "status value during error handling");
329 SkillerExecutionThread::publish_skdbg()
332 __lua->
do_string(
"skillenv.write_skiller_debug(interfaces.writing.skdbg, \"%s\", \"%s\", %s)",
333 __skdbg_what.c_str(), __skdbg_graphdir.c_str(),
334 __skdbg_graphcolored ?
"true" :
"false");
336 logger->
log_warn(
"SkillerExecutionThread",
"Error writing graph");
342 SkillerExecutionThread::lua_loop_reset()
345 __lua->
do_string(
"skillenv.reset_loop()");
347 logger->
log_warn(
"SkillerExecutionThread",
"Lua Loop Reset failed");
354 SkillerExecutionThread::publish_error()
357 __lua->
do_string(
"skillenv.write_fsm_error(skillenv.get_skill_fsm(skillenv.get_active_skills()), interfaces.writing.skiller)");
359 logger->
log_warn(
"SkillerExecutionThread",
"Error writing error");
361 __skiller_if->
set_error(
"Failed to set Lua error");
362 __skiller_if->
write();
368 SkillerExecutionThread::process_skdbg_messages()
378 case SkillerDebugInterface::GD_BOTTOM_TOP: __skdbg_graphdir =
"BT";
break;
379 case SkillerDebugInterface::GD_LEFT_RIGHT: __skdbg_graphdir =
"LR";
break;
380 case SkillerDebugInterface::GD_RIGHT_LEFT: __skdbg_graphdir =
"RL";
break;
381 default: __skdbg_graphdir =
"TB";
break;
397 #ifdef SKILLER_TIMETRACKING
398 __tt->ping_start(__ttc_total);
406 std::string curss =
"";
409 bool write_skiller_if =
false;
410 bool last_was_continuous = __continuous_run;
412 #ifdef SKILLER_TIMETRACKING
413 __tt->ping_start(__ttc_msgproc);
415 process_skdbg_messages();
420 if ( excl_ctrl == 0 ) {
421 logger->
log_debug(
"SkillerExecutionThread",
"%s is new exclusive controller",
424 write_skiller_if =
true;
426 }
else if (excl_ctrl == m->
sender_id()) {
430 "exclusive control, but another controller exists "
437 logger->
log_debug(
"SkillerExecutionThread",
"%s releases exclusive control",
440 if ( __continuous_run ) {
441 __continuous_run =
false;
442 __continuous_reset =
true;
446 write_skiller_if =
true;
449 if ( !__reader_just_left || (m->
sender_id() != __last_exclusive_controller)) {
450 logger->
log_warn(
"SkillerExecutionThread",
"%s tried to release exclusive control, "
459 logger->
log_warn(
"SkillerExecutionThread",
"More than one skill string enqueued, "
460 "ignoring previous string (%s).", curss.c_str());
462 logger->
log_debug(
"SkillerExecutionThread",
"%s wants me to execute '%s'",
465 if ( __continuous_run ) {
466 __continuous_run =
false;
467 __continuous_reset =
true;
471 logger->
log_debug(
"SkillerExecutionThread",
"%s tries to exec while not controller",
480 logger->
log_warn(
"SkillerExecutionThread",
"More than one skill string enqueued, "
483 logger->
log_debug(
"SkillerExecutionThread",
"%s wants me to continuously execute '%s'",
487 __continuous_reset = last_was_continuous;
488 __continuous_run =
true;
491 logger->
log_debug(
"SkillerExecutionThread",
"%s tries to exec while not controller",
499 (__reader_just_left && (m->
sender_id() == __last_exclusive_controller)) ) {
500 logger->
log_debug(
"SkillerExecutionThread",
"Stopping continuous execution");
501 if ( __continuous_run ) {
502 __continuous_run =
false;
503 __continuous_reset =
true;
507 logger->
log_debug(
"SkillerExecutionThread",
"%s tries to stop exec while not controller",
511 logger->
log_warn(
"SkillerExecutionThread",
"Unhandled message of type %s in "
518 if ( __continuous_run && (curss ==
"") ) {
522 #ifdef SKILLER_TIMETRACKING
523 __tt->ping_end(__ttc_msgproc);
526 if ( __continuous_reset ) {
527 logger->
log_debug(
"SkillerExecutionThread",
"Continuous reset forced");
try {
529 __sksf_pushed =
false;
532 __lua->
do_string(
"skillenv.reset_all()");
534 logger->
log_warn(
"SkillerExecutionThread",
"Caught exception while resetting skills, ignored, output follows");
538 __skiller_if->
set_status(SkillerInterface::S_INACTIVE);
543 __error_written =
false;
544 __continuous_reset =
false;
545 write_skiller_if =
true;
548 if ( write_skiller_if ) __skiller_if->
write();
553 #ifdef SKILLER_TIMETRACKING
554 __tt->ping_start(__ttc_luaprep);
558 if ( __continuous_run ) {
562 __lua->
do_string(
"skillenv.reset_status()");
564 logger->
log_warn(
"SkillerExecutionThread",
"Caught exception while resetting status, ignored, output follows");
570 if (! __sksf_pushed) {
573 __lua->
do_string(
"return skillenv.gensandbox()");
575 __sksf_pushed =
true;
577 #ifdef SKILLER_TIMETRACKING
578 __tt->ping_end(__ttc_luaprep);
579 __tt->ping_start(__ttc_luaexec);
586 __skiller_if->
set_error(
"Skill string execution failed with Lua error, see log");
587 __skiller_if->
write();
588 __continuous_reset =
true;
589 __continuous_run =
false;
591 #ifdef SKILLER_TIMETRACKING
592 __tt->ping_end(__ttc_luaexec);
595 if ( ! __continuous_run ) {
600 __sksf_pushed =
false;
603 __lua->
do_string(
"skillenv.reset_all()");
605 logger->
log_warn(
"SkillerExecutionThread",
"Caught exception while resetting skills, ignored, output follows");
612 #ifdef SKILLER_TIMETRACKING
613 __tt->ping_start(__ttc_publish);
615 publish_skill_status(curss);
619 __reader_just_left =
false;
622 #ifdef SKILLER_TIMETRACKING
623 __tt->ping_end(__ttc_publish);
624 __tt->ping_end(__ttc_total);
625 if (++__tt_loopcount >= SKILLER_TT_MOD) {
628 __tt->print_to_stdout();