22#include "clips_executive_thread.h"
24#include <core/threading/mutex_locker.h>
25#include <interfaces/SwitchInterface.h>
26#include <utils/misc/map_skill.h>
27#include <utils/misc/string_conversions.h>
28#include <utils/misc/string_split.h>
40:
Thread(
"ClipsExecutiveThread",
Thread::OPMODE_WAITFORWAKEUP),
54 cfg_assert_time_each_loop_ =
false;
56 cfg_assert_time_each_loop_ =
config->
get_bool(
"/clips-executive/assert-time-each-loop");
60 std::vector<std::string> clips_dirs;
63 for (
size_t i = 0; i < clips_dirs.size(); ++i) {
64 if (clips_dirs[i][clips_dirs[i].size() - 1] !=
'/') {
71 clips_dirs.insert(clips_dirs.begin(), std::string(SRCDIR) +
"/clips/");
76 std::string action_mapping_cfgpath =
77 std::string(
"/clips-executive/specs/") + cfg_spec +
"/action-mapping/";
78#if __cplusplus >= 201103L
79 std::unique_ptr<Configuration::ValueIterator> v(
config->
search(action_mapping_cfgpath.c_str()));
81 std::auto_ptr<Configuration::ValueIterator> v(config_->search(action_mapping_cfgpath.c_str()));
83 std::map<std::string, std::string> mapping;
85 std::string action_name = std::string(v->path()).substr(action_mapping_cfgpath.length());
86 mapping[action_name] = v->get_as_string();
88 "Adding action mapping '%s' -> '%s'",
90 v->get_as_string().c_str());
93 action_skill_mapping_ = std::make_shared<fawkes::ActionSkillMapping>(mapping);
99 clips->evaluate(std::string(
"(path-add-subst \"@BASEDIR@\" \"") + BASEDIR +
"\")");
100 clips->evaluate(std::string(
"(path-add-subst \"@FAWKES_BASEDIR@\" \"") + FAWKES_BASEDIR +
"\")");
101 clips->evaluate(std::string(
"(path-add-subst \"@RESDIR@\" \"") + RESDIR +
"\")");
102 clips->evaluate(std::string(
"(path-add-subst \"@CONFDIR@\" \"") + CONFDIR +
"\")");
104 for (
size_t i = 0; i < clips_dirs.size(); ++i) {
105 clips->evaluate(
"(path-add \"" + clips_dirs[i] +
"\")");
108 clips->evaluate(
"(ff-feature-request \"config\")");
110 clips->add_function(
"map-action-skill",
111 sigc::slot<std::string, std::string, CLIPS::Values, CLIPS::Values>(
112 sigc::mem_fun(*
this, &ClipsExecutiveThread::clips_map_skill)));
114 bool cfg_req_redefwarn_feature =
true;
116 cfg_req_redefwarn_feature =
117 config->
get_bool(
"/clips-executive/request-redefine-warning-feature");
120 if (cfg_req_redefwarn_feature) {
122 clips->evaluate(
"(ff-feature-request \"redefine-warning\")");
125 std::vector<std::string> files{SRCDIR
"/clips/saliences.clp", SRCDIR
"/clips/init.clp"};
126 for (
const auto &f : files) {
127 if (!
clips->batch_evaluate(f)) {
129 "Failed to initialize CLIPS environment, "
130 "batch file '%s' failed.",
132 throw Exception(
"Failed to initialize CLIPS environment, batch file '%s' failed.", f.c_str());
136 clips->assert_fact(
"(executive-init)");
137 clips->refresh_agenda();
142 CLIPS::Fact::pointer fact =
clips->get_facts();
144 CLIPS::Template::pointer tmpl = fact->get_template();
145 if (tmpl->name() ==
"executive-init-stage") {
146 CLIPS::Values v = fact->slot_value(
"");
147 if (v.size() > 0 && v[0].as_string() ==
"FAILED") {
148 throw Exception(
"CLIPS Executive initialization failed");
160 clips->assert_fact(
"(executive-finalize)");
161 clips->refresh_agenda();
172 if (cfg_assert_time_each_loop_) {
173 clips->assert_fact(
"(time (now))");
176 clips->refresh_agenda();
181ClipsExecutiveThread::clips_map_skill(std::string action_name,
182 CLIPS::Values param_names,
183 CLIPS::Values param_values)
185 if (!action_skill_mapping_) {
189 if (action_name ==
"") {
193 if (!action_skill_mapping_->has_mapping(action_name)) {
197 if (param_names.size() != param_values.size()) {
199 "Number of parameter names and values "
200 "do not match for action '%s'",
201 action_name.c_str());
204 std::map<std::string, std::string> param_map;
205 for (
size_t i = 0; i < param_names.size(); ++i) {
206 if (param_names[i].type() != CLIPS::TYPE_SYMBOL
207 && param_names[i].type() != CLIPS::TYPE_STRING) {
208 logger->
log_error(
name(),
"Param for '%s' is not a string or symbol", action_name.c_str());
211 switch (param_values[i].type()) {
212 case CLIPS::TYPE_FLOAT:
213 param_map[param_names[i].as_string()] = std::to_string(param_values[i].as_float());
215 case CLIPS::TYPE_INTEGER:
216 param_map[param_names[i].as_string()] = std::to_string(param_values[i].as_integer());
218 case CLIPS::TYPE_SYMBOL:
219 case CLIPS::TYPE_STRING:
220 param_map[param_names[i].as_string()] = param_values[i].as_string();
224 "Param '%s' for action '%s' of invalid type",
225 param_names[i].as_string().c_str(),
226 action_name.c_str());
231 std::multimap<std::string, std::string> messages;
232 std::string rv = action_skill_mapping_->map_skill(action_name, param_map, messages);
233 for (
auto &m : messages) {
234 if (m.first ==
"WARN") {
236 }
else if (m.first ==
"ERROR") {
238 }
else if (m.first ==
"DEBUG") {
ClipsExecutiveThread()
Constructor.
virtual void loop()
Code to execute in the thread.
virtual void finalize()
Finalize the thread.
virtual void init()
Initialize the thread.
virtual ~ClipsExecutiveThread()
Destructor.
Thread aspect to use blocked timing.
Thread aspect to get access to a CLIPS environment.
LockPtr< CLIPS::Environment > clips
CLIPS environment for exclusive usage.
Configuration * config
This is the Configuration member used to access the configuration.
virtual bool get_bool(const char *path)=0
Get value from configuration which is of type bool.
virtual std::vector< std::string > get_strings(const char *path)=0
Get list of values from configuration which is of type string.
virtual ValueIterator * search(const char *path)=0
Iterator with search results.
virtual std::string get_string(const char *path)=0
Get value from configuration which is of type string.
Base class for exceptions in Fawkes.
Mutex * objmutex_ptr() const
Get object mutex.
virtual void log_debug(const char *component, const char *format,...)=0
Log debug message.
virtual void log_warn(const char *component, const char *format,...)=0
Log warning message.
virtual void log_error(const char *component, const char *format,...)=0
Log error message.
virtual void log_info(const char *component, const char *format,...)=0
Log informational message.
Logger * logger
This is the Logger member used to access the logger.
Thread class encapsulation of pthreads.
const char * name() const
Get name of thread.
Fawkes library namespace.