21#include "exog_manager.h"
23#include "execution_thread.h"
26#include <core/exception.h>
27#include <golog++/model/grounding.h>
28#include <libs/interface/field_iterator.h>
31using namespace gologpp;
36const std::unordered_map<interface_fieldtype_t, std::string> ExogManager::iface_type_to_golog_type_{
38 {
IFT_BYTE, NumberType::static_name()},
39 {
IFT_ENUM, SymbolType::static_name()},
40 {
IFT_INT8, NumberType::static_name()},
80 const std::string &cfg_prefix,
83: exec_thread_(exec_thread), config_(config), blackboard_(blackboard), logger_(logger)
87 for (shared_ptr<Global> g : global_scope().globals()) {
88 shared_ptr<ExogAction> exog = std::dynamic_pointer_cast<ExogAction>(g);
90 mapped_exogs_.emplace(exog->mapping().backend_name(), exog);
96 for (
const string &
id :
98 shared_ptr<ExogAction> exog = find_mapped_exog(
id);
99 watchers_.push_back(std::make_unique<InterfaceWatcher>(blackboard,
id, exog, *
this));
102 for (
const string &pattern :
104 shared_ptr<ExogAction> exog = find_mapped_exog(pattern);
105 observers_.push_back(std::make_unique<PatternObserver>(blackboard, pattern, exog, *
this));
115 return "ExogManager";
118shared_ptr<ExogAction>
119ExogManager::find_mapped_exog(
const std::string &mapped_name)
121 auto map_it = mapped_exogs_.find(mapped_name);
123 if (map_it == mapped_exogs_.end())
124 throw ConfigError(
"No exogenous action handles " + mapped_name);
126 return map_it->second;
130ExogManager::exog_queue_push(shared_ptr<ExogEvent> evt)
140ExogManager::BlackboardEventHandler::BlackboardEventHandler(
142 gologpp::shared_ptr<gologpp::ExogAction> exog,
143 ExogManager & exog_mgr)
144: blackboard_(bb), target_exog_(exog), exog_manager_(exog_mgr)
146 for (
const auto &pair : target_exog_->mapping().arg_mapping()) {
154 auto &var_ref =
dynamic_cast<Reference<Variable> &
>(*pair.second);
157 string iface_type = extract_type_name(target_exog_->mapping().backend_name());
159 blackboard_->
open_for_reading(iface_type.c_str(),
"/gologpp_interface_analysis");
166 throw ConfigError(
"Interface type " + iface_type +
" does not have a field `" + pair.first
169 auto it = iface_type_to_golog_type_.find(fi.
get_type());
170 if (it == iface_type_to_golog_type_.end()) {
174 shared_ptr<const Type> desired_type = gologpp::global_scope().lookup_type(it->second);
176 throw Exception(
"Type %s required for field %s is not defined in the golog++ code model",
180 if (!(*desired_type <= gologpp::get_type<StringType>()
181 || *desired_type >= gologpp::get_type<StringType>())
183 desired_type = gologpp::global_scope().lookup_list_type(*desired_type);
186 if (!(var_ref.type() <= *desired_type || var_ref.type() >= *desired_type)) {
187 throw ConfigError(target_exog_->name() +
"'s argument " + var_ref.target()->name() +
" is a "
188 + var_ref.type().name() +
", but the interface field requires "
189 + desired_type->name());
191 blackboard_->
close(iface);
194 std::find(target_exog_->params().begin(), target_exog_->params().end(), var_ref.target());
195 auto param_idx = param_it - target_exog_->params().begin();
196 fields_order_.emplace(pair.first, arity_t(param_idx));
201ExogManager::BlackboardEventHandler::extract_type_name(
const std::string &iface_uid)
203 auto idx = iface_uid.find(
"::");
204 if (idx == std::string::npos)
205 throw ConfigError(iface_uid +
" is not an interface UID. Must be IFACE_TYPE::IFACE_ID.");
206 return iface_uid.substr(0, idx);
210ExogManager::BlackboardEventHandler::extract_id(
const std::string &iface_uid)
212 auto idx = iface_uid.find(
"::");
213 if (idx == std::string::npos)
214 throw ConfigError(iface_uid +
" is not an interface UID. Must be IFACE_TYPE::IFACE_ID.");
215 return iface_uid.substr(idx + 2);
218ExogManager::InterfaceWatcher::InterfaceWatcher(
BlackBoard * bb,
220 shared_ptr<ExogAction> exog,
221 ExogManager & exog_mgr)
222: BlackboardEventHandler(bb, exog, exog_mgr),
224 iface_(blackboard_->open_for_reading(extract_type_name(uid).c_str(), extract_id(uid).c_str()))
226 bbil_add_data_interface(iface_);
230ExogManager::InterfaceWatcher::~InterfaceWatcher()
232 blackboard_->unregister_listener(
this);
233 blackboard_->close(iface_);
237ExogManager::BlackboardEventHandler::make_exog_event(
Interface *iface)
const
243 vector<unique_ptr<Value>> args(target_exog_->arity());
246 if (target_exog_->mapping().is_mapped(fi.
get_name())) {
247 auto order_it = fields_order_.find(fi.
get_name());
250 args[order_it->second].reset(field_to_value(fi, 0));
252 vector<unique_ptr<Value>> list_init;
253 for (
unsigned int idx = 0; idx < fi.
get_length(); ++idx)
254 list_init.emplace_back(
255 field_to_value(fi, idx)
257 shared_ptr<const Type> list_type = global_scope().lookup_list_type(list_init[0]->type());
258 args[order_it->second].reset(
259 new Value(*list_type, list_init)
269 return std::make_shared<ExogEvent>(target_exog_, std::move(args));
274ExogManager::InterfaceWatcher::bb_interface_data_refreshed(
Interface *iface)
noexcept
277 exog_manager_.exog_queue_push(make_exog_event(iface));
279 exog_manager_.logger_->log_error(exog_manager_.name(),
280 "Error when creating exogenous event: %s, ignoring event!",
282 }
catch (gologpp::UserError &e) {
283 exog_manager_.logger_->log_error(exog_manager_.name(),
284 "Error when creating exogenous event: %s, ignoring event!",
289ExogManager::PatternObserver::PatternObserver(
BlackBoard * bb,
290 const std::string & pattern,
291 shared_ptr<ExogAction> exog,
292 ExogManager & exog_mgr)
293: BlackboardEventHandler(bb, exog, exog_mgr)
295 bbio_add_observed_create(extract_type_name(pattern).c_str(), extract_id(pattern).c_str());
299ExogManager::PatternObserver::~PatternObserver()
301 blackboard_->unregister_observer(
this);
305ExogManager::PatternObserver::bb_interface_created(
const char *type,
const char *
id)
noexcept
307 std::lock_guard<std::mutex> locked{handler_mutex_};
308 exog_manager_.watchers_.push_back(std::make_unique<InterfaceWatcher>(
309 blackboard_,
string(type) +
"::" +
id, target_exog_, exog_manager_));
BlackBoard interface listener.
The BlackBoard abstract class.
virtual Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)=0
Open interface for reading.
@ BBIL_FLAG_DATA
consider data events
virtual void register_observer(BlackBoardInterfaceObserver *observer)
Register BB interface observer.
virtual void register_listener(BlackBoardInterfaceListener *listener, ListenerRegisterFlag flag=BBIL_FLAG_ALL)
Register BB event listener.
virtual void close(Interface *interface)=0
Close interface.
Interface for configuration handling.
virtual std::vector< std::string > get_strings_or_defaults(const char *path, const std::vector< std::string > &default_val)
Get list of values from configuration which is of type string, or the given default if the path does ...
Base class for exceptions in Fawkes.
virtual const char * what_no_backtrace() const noexcept
Get primary string (does not implicitly print the back trace).
Expected parameter is missing.
Interface field iterator.
size_t get_length() const
Get length of current field.
interface_fieldtype_t get_type() const
Get type of current field.
const char * get_name() const
Get name of current field.
const char * get_typename() const
Get type of current field as string.
Base class for all Fawkes BlackBoard interfaces.
InterfaceFieldIterator fields_end()
Invalid iterator.
InterfaceFieldIterator fields()
Get iterator over all fields of this interface instance.
const char * uid() const
Get unique identifier of interface.
void read()
Read from BlackBoard into local copy.
Thrown if the config is somehow inconsistent with the agent program.
ConfigError(const std::string &)
Construct a ConfigError.
const char * name()
Get the ExogManager's thread name.
ExogManager(GologppThread *exec_thread, Configuration *, const std::string &cfg_prefix, BlackBoard *, Logger *)
Constructor.
Main golog++ thread that handles program execution, i.e.
gologpp::ExecutionContext & gologpp_context()
GologppThread::gologpp_context.
Fawkes library namespace.
@ IFT_INT8
8 bit integer field
@ IFT_UINT32
32 bit unsigned integer field
@ IFT_BYTE
byte field, alias for uint8
@ IFT_UINT64
64 bit unsigned integer field
@ IFT_UINT16
16 bit unsigned integer field
@ IFT_INT32
32 bit integer field
@ IFT_INT64
64 bit integer field
@ IFT_INT16
16 bit integer field
@ IFT_ENUM
field with interface specific enum type
@ IFT_UINT8
8 bit unsigned integer field