/*! \file \brief ARX Agents for MPDM \author Vaclav Smidl. */ #ifndef ARXAG_H #define ARXAG_H #include #include #include namespace bdm { /*! \brief ARX agent */ class ARXAgent : public Participant { protected: //! Pointers to neighbours Array neighbours; //! Internal ARX Controller shared_ptr lqg_arx; //! Merger for predictors from neighbours shared_ptr merger; //! All available predictors Array > preds; //! My own predictor mlnorm_chmat_ptr my_pred; //! data link of data datalink_part dlU; //! data link of datalink_buffered dlDt; //! internal data vector for controller vec dt; //! internal data vector for controller output vec ut; public: void validate() { lqg_arx->validate(); my_pred=lqg_arx->_ar().ml_predictor(); } void receive(const Setting &msg) { string what; UI::get(what, msg, "what", UI::compulsory); if (what=="predictor") { // add predictor preds.set_length(preds.length()+1, true); preds(preds.length()-1) = UI::build(msg["data"]); } else { bdm_warning("Unknown message of type "+what); } } void broadcast(Setting& set) { // broadcast predictor (created in adapt) to all neighbours for (int i=0; iadapt(dt); // remove old predictors preds.set_length(1, false); lqg_arx->_ar().ml_predictor_update(*my_pred) ; preds(0)=my_pred; // we arer finished with datasource } void act(vec &glob_ut) { if (preds.length()>1) { merger->set_sources(preds); if (preds.length()>1) { cout<to_string()<merge(); enorm joint_pred; mat Cov=merger->merger().covariance(); if (sumsum(Cov)==0.0) { bdm_error("merging failed"); } joint_pred.set_parameters(merger->merger().mean(), Cov); joint_pred.set_rv(merger->merger()._rv()); enorm marg_pred; // remove rvs taht should not be there joint_pred.marginal(concat(preds(0)->_rv(), preds(0)->_rvc()), marg_pred); // assign mlnorm *merg_pred = lqg_arx->_pred(); marg_pred.condition(preds(0)->_rv(),*merg_pred); } else { lqg_arx->_ar().ml_predictor_update(*lqg_arx->_pred()) ; } // lqg_arx->redesign(); ut=lqg_arx->ctrlaction(dt); dlU.filldown(ut,glob_ut); } virtual void ds_register(const DS &ds) { dlDt.set_connection(lqg_arx->_rvc(), ds._drv() ); dlU.set_connection(ds._urv() , lqg_arx->_rv() ); dt=zeros(lqg_arx->_rvc()._dsize()); ut=zeros(lqg_arx->_rv()._dsize()); } void from_setting(const Setting &set) { Participant::from_setting(set); lqg_arx = UI::build(set, "lqg_arx",UI::compulsory); merger = UI::build(set, "merger", UI::compulsory); UI::get(neighbours, set, "neighbours",UI::compulsory); validate(); } }; //UIREGISTER(LQG_ARX); UIREGISTER(ARXAgent); }//namespace #endif //ARXAG_H