22 #include "clips_agent_thread.h"
24 #include <core/threading/mutex_locker.h>
25 #include <interfaces/SwitchInterface.h>
26 #include <utils/misc/string_conversions.h>
27 #include <utils/misc/string_split.h>
39 :
Thread(
"ClipsAgentThread",
Thread::OPMODE_WAITFORWAKEUP),
55 cfg_auto_start_ =
false;
56 cfg_assert_time_each_loop_ =
false;
57 cfg_skill_sim_time_ = 2.0;
58 cfg_skill_sim_ =
false;
59 cfg_steal_skiller_control_ =
true;
66 cfg_assert_time_each_loop_ =
config->
get_bool(
"/clips-agent/assert-time-each-loop");
78 cfg_steal_skiller_control_ =
config->
get_bool(
"/clips-agent/steal-skiller-control");
82 std::vector<std::string> clips_dirs;
85 for (
size_t i = 0; i < clips_dirs.size(); ++i) {
86 if (clips_dirs[i][clips_dirs[i].size() - 1] !=
'/') {
93 clips_dirs.insert(clips_dirs.begin(), std::string(SRCDIR) +
"/clips/");
95 if (!cfg_skill_sim_) {
100 throw Exception(
"Skiller has no writer, aborting");
104 throw Exception(
"Skiller already has a different exclusive controller");
112 clips->evaluate(std::string(
"(path-add-subst \"@BASEDIR@\" \"") + BASEDIR +
"\")");
113 clips->evaluate(std::string(
"(path-add-subst \"@FAWKES_BASEDIR@\" \"") + FAWKES_BASEDIR +
"\")");
114 clips->evaluate(std::string(
"(path-add-subst \"@RESDIR@\" \"") + RESDIR +
"\")");
115 clips->evaluate(std::string(
"(path-add-subst \"@CONFDIR@\" \"") + CONFDIR +
"\")");
117 for (
size_t i = 0; i < clips_dirs.size(); ++i) {
118 clips->evaluate(
"(path-add \"" + clips_dirs[i] +
"\")");
121 clips->add_function(
"skill-call-ext",
122 sigc::slot<void, std::string, std::string>(
123 sigc::mem_fun(*
this, &ClipsAgentThread::clips_skill_call_ext)));
125 clips->evaluate(
"(ff-feature-request \"config\")");
127 bool cfg_req_redefwarn_feature =
true;
129 cfg_req_redefwarn_feature =
config->
get_bool(
"/clips-agent/request-redefine-warning-feature");
132 if (cfg_req_redefwarn_feature) {
134 clips->evaluate(
"(ff-feature-request \"redefine-warning\")");
137 if (!
clips->batch_evaluate(SRCDIR
"/clips/init.clp")) {
139 "Failed to initialize CLIPS environment, "
140 "batch file failed.");
142 throw Exception(
"Failed to initialize CLIPS environment, batch file failed.");
145 clips->assert_fact(
"(agent-init)");
146 clips->refresh_agenda();
149 ctrl_recheck_ =
true;
158 clips->remove_function(
"skill-call-ext");
160 if (!cfg_skill_sim_ && skiller_if_->
has_writer()) {
174 if (!started_ && cfg_auto_start_) {
175 clips->assert_fact(
"(start)");
179 if (!cfg_skill_sim_) {
189 ctrl_recheck_ =
false;
191 ctrl_recheck_ =
true;
200 clips->assert_fact(
"(start)");
207 if (cfg_assert_time_each_loop_) {
208 clips->assert_fact(
"(time (now))");
212 if (!active_skills_.empty()) {
216 std::list<std::string> finished_skills;
217 std::map<std::string, SkillExecInfo>::iterator as;
218 for (as = active_skills_.begin(); as != active_skills_.end(); ++as) {
219 const std::string & as_name = as->first;
220 const SkillExecInfo &as_info = as->second;
222 if (cfg_skill_sim_) {
223 if ((now - as_info.start_time) >= cfg_skill_sim_time_) {
225 clips->assert_fact_f(
"(skill-update (name \"%s\") (status FINAL))", as_name.c_str());
226 finished_skills.push_back(as_name);
228 clips->assert_fact_f(
"(skill-update (name \"%s\") (status RUNNING))", as_name.c_str());
231 if (as_info.skill_string == skiller_if_->
skill_string()) {
232 clips->assert_fact_f(
"(skill-update (name \"%s\") (status %s))",
234 status_string(skiller_if_->
status()));
235 if (skiller_if_->
status() == SkillerInterface::S_FINAL
236 || skiller_if_->
status() == SkillerInterface::S_FAILED) {
237 finished_skills.push_back(as_name);
243 std::list<std::string>::iterator fs;
244 for (fs = finished_skills.begin(); fs != finished_skills.end(); ++fs) {
245 active_skills_.erase(*fs);
249 clips->refresh_agenda();
257 case SkillerInterface::S_FINAL:
return "FINAL";
258 case SkillerInterface::S_FAILED:
return "FAILED";
259 case SkillerInterface::S_RUNNING:
return "RUNNING";
260 default:
return "IDLE";
265 ClipsAgentThread::clips_skill_call_ext(std::string skill_name, std::string skill_string)
267 if (active_skills_.find(skill_name) != active_skills_.end()) {
268 logger->
log_warn(
name(),
"Skill %s called again while already active", skill_name.c_str());
271 if (cfg_skill_sim_) {
285 sei.skill_string = skill_string;
286 active_skills_[skill_name] = sei;