root/applications/pmsm/pmsm_ctrl.cpp

Revision 1252, 8.0 kB (checked in by smidl, 14 years ago)

add fixed filters to ctrl simulator

Line 
1/*!
2\file
3\brief Application Estimator
4
5The general task of estimation is defined on the following scheme:
6\dot
7digraph estimation{
8        node [shape=box];
9        subgraph cl0 {
10        "Data Source" -> "Controller" [label="observations"];
11        "Controller" -> "Data Source" [label="actions"];
12        }
13        {rank="same"; "Controller"; "Result Logger"}
14        "Controller" -> "Result Logger" [label="internals"];
15        "Data Source" -> "Result Logger" [label="Simulated\n data"];
16}
17\enddot
18
19Here,
20\li Data Source is an object (class DS) providing sequential data, \f$ [d_1, d_2, \ldots d_t] \f$.
21\li Bayesian Model is an object (class BM) performing Bayesian filtering,
22\li Result Logger is an object (class logger) dedicated to storing important data from the experiment.
23
24\section  cmd Command-line usage
25Execute command:
26\code
27$> estimator config_file.cfg
28\endcode
29
30Full description of the experiment is in the file config_file.cfg which is expected to have the following structure:
31\code
32system = {type = "DS_offspring", ...};      // definition of a data source
33estimator = {type = "BM_offspring", ...};   // definition of an estimator
34logger = {type = "logger_type",...};        // definition of a logger
35experiment = {ndat = 11000; };              // definition of number of data records
36\endcode
37
38The above description must be specialized to specific classes. See, \subpage arx_ui how to do it for estimation of an ARX model.
39
40\section ex Matlab usage
41Execute command:
42\code
43>> estimator('config_file.cfg');
44\endcode
45when using loggers storing results on hard drives, and
46\code
47>> Res=estimator('config_file.cfg');
48\endcode
49when using logger of the type \c "mex_logger". The results will be stored in structure \c M.
50
51 */
52
53#include <estim/arx.h>
54#include <stat/emix.h>
55#include <base/datasources.h>
56#include <base/loggers.h>
57#include <design/arx_ctrl.h>
58
59//PMSM special
60#include "pmsm_ctrl.h"
61#include "pmsmDS.h"
62#include "simulator_zdenek/ekf_example/ekf_obj.h"
63
64using namespace bdm;
65
66#ifdef MEX
67#include <itpp/itmex.h>
68#include <mex/mex_BM.h>
69#include <mex/mex_logger.h>
70#include <mex/mex_datasource.h>
71#include <mex/mex_function.h>
72
73void mexFunction ( int n_output, mxArray *output[], int n_input, const mxArray *input[] ) {
74        // Check the number of inputs and output arguments
75        if ( n_input<2 ) mexErrMsgTxt ( "Usage:\n"
76                                                "result=controlloop(system, controllers, experiment, logger)\n"
77                                                "  system     = struct('class','datasource',...);  % Estimated system\n"
78                                                "  controllers= {struct('class','controller',...),  % Controllers\n"
79                                                "                struct('class','controller',...),...} \n"
80                                                "  === optional ==="
81                                                "  experiment = struct('ndat',100,...              % number of data in experiment, full length of finite datasources, 100 otherwise \n"
82                                                "               'seed',[],...                      % seed for random number generator\n"
83                                                "               'burnin',10,...                    % initial time with different control\n"
84                                                "               'burn_pdf', struct('class','epdf_offspring') );\n"
85                                                "                                                  % sampler of the initial control\n"
86                                                "  logger     = struct('class','mexlogger');       % How to store results, default=mexlog, i.e. matlab structure\n\n"
87                                                "see documentation of classes datasource, BM, and mexlogger and their offsprings in BDM." );
88
89        RV::clear_all();
90        //CONFIG
91        UImxArray Cfg;
92        try {
93                Cfg.addGroup ( input[0],"system" );
94                Cfg.addList ( input[1],"controllers" );
95                if ( n_input>2 ) {
96                        Cfg.addGroup ( input[2],"experiment" );
97                }
98                if ( n_input>3 ) {
99                        Cfg.addGroup ( input[3],"logger" );
100                }
101        } catch ( SettingException e ) {
102                it_error ( "error: "+string ( e.getPath() ) );
103        }
104
105        //DBG
106        Cfg.writeFile ( "controlloop.cfg" );
107
108#else
109int main ( int argc, char* argv[] ) {
110        const char *fname;
111        if ( argc>1 ) {
112                fname = argv[1];
113        } else {
114                fname="controlloop.cfg";
115        }
116        UIFile Cfg ( fname );
117#endif
118
119        RNG_randomize();
120       
121        shared_ptr<DS> Ds = UI::build<DS> ( Cfg, "system" );
122        Array<shared_ptr<Controller> > Cs;
123        UI::get ( Cs,Cfg, "controllers" );
124        int Ndat=100;
125        int burnin=0;
126        shared_ptr<epdf> burn_pdf; 
127       
128        if ( Cfg.exists ( "experiment" ) ) {
129                Setting &exper=Cfg.getRoot()["experiment"];
130                // get number of data
131                if (UI::get(Ndat, exper, "Ndat", UI::optional ) ) {
132                        bdm_assert ( Ndat<=Ds->max_length(), "Data source has less data then required" );
133                };
134                // check for seed
135                int seed;
136                if (UI::get(seed, exper, "seed", UI::optional)){
137                        RNG_reset(seed);
138                }
139                // process burnin
140                if (UI::get(burnin, exper, "burnin",UI::optional )){
141                        burn_pdf = UI::build<epdf>(exper,"burn_pdf", UI::compulsory);
142                        if (burn_pdf){
143                                bdm_assert(burn_pdf->dimension()==Ds->_urv()._dsize(),"Given burn_pdf does not match the DataSource");
144                        } else {
145                                bdm_error("burn_pdf not specified!");
146                        }
147                       
148                }
149        } else {
150                if ( Ds->max_length() < std::numeric_limits< int >::max() ) {
151                        Ndat=Ds->max_length();
152                }
153                ;// else Ndat=10;
154        }
155        shared_ptr<logger> L = UI::build<logger> ( Cfg, "logger",UI::optional );
156        if ( !L ) {
157#ifdef MEX
158                //mex logger has only from_setting constructor - we  have to fill it...
159                L=new mexlog ( Ndat );
160#else
161                L=new stdlog();
162#endif
163        }
164
165        Ds->log_register ( *L, "DS" );
166        bdm_assert((Ds->_urv()._dsize() > 0), "Given DataSource is not controllable");
167        string Cname;
168        Setting &S=Cfg;
169        for ( int i=0; i<Cs.length(); i++ ) {
170                if (!UI::get ( Cname, S["controllers"][i], "name" ,UI::optional)){
171                        Cname="Ctrl"+num2str ( i );
172                }
173               
174                Cs ( i )->log_register ( *L,Cname ); // estimate
175        }
176        L->init();
177
178        vec dt=zeros ( Ds->_drv()._dsize() );   //data variable
179        Array<datalink_part*> Dlsu ( Cs.length() );
180        Array<datalink*> Dlsc ( Cs.length() );
181        Array<datalink_buffered*> Dls_buf (0);
182        for ( int i=0; i<Cs.length(); i++ ) {
183                //connect actual data
184                Dlsu ( i ) = new datalink_part;
185                Dlsu(i)->set_connection( Ds->_urv(), Cs ( i )->_rv()); //datalink controller -> datasource
186                //connect data in condition: datasource -> controller
187                if (Cs ( i )->_rvc().mint()<0){ 
188                        //delayed values are required
189                       
190                        //create delayed dl
191                        int ith_buf=Dls_buf.size();
192                        Dls_buf.set_size( ith_buf + 1, true);
193                        Dls_buf(ith_buf) = new datalink_buffered(); 
194                        //add dl to list of buffered DS
195                        Dlsc(i) = Dls_buf(ith_buf);
196                        Dlsc(i)->set_connection ( Cs ( i )->_rvc(),Ds->_drv() ); //datalink between a datasource and estimator
197                       
198                        bdm_assert_debug(Dlsc(i)->_downsize() == Cs ( i )->_rvc()._dsize(), "Data required by Controler[" + num2str(i) + "], " + 
199                        Cs(i)->_rvc().to_string() + ", are not available in DS drv:" + Ds->_drv().to_string(););
200                       
201                } else {
202                        Dlsc ( i ) = new datalink ( Cs ( i )->_rvc(),Ds->_drv() ); //datalink between a datasource and estimator
203                }
204        }
205
206        vec ut(Ds->_urv()._dsize());
207        for ( int tK=0;tK<Ndat;tK++ ) {
208                Ds->getdata ( dt );                                     // read data
209                Ds->log_write ( );
210
211                for ( int i=0; i<Cs.length(); i++ ) {
212                        if (tK + Cs ( i )->_rvc().mint() > 0 ) {
213                                Cs(i) -> redesign();
214                                Cs(i) -> adapt( Dlsc(i) ->pushdown(dt));
215                                if (tK >= burnin){
216                                        vec uti=Cs ( i )->ctrlaction ( Dlsc(i) ->pushdown(dt) );                // update estimates
217                                        Dlsu(i)->filldown(uti, ut);
218                                }
219                        }
220                        if(tK<burnin) {
221                                ut = burn_pdf->sample();
222                        }
223                       
224                        Cs ( i )->log_write ();
225                }
226                Ds->write(ut);
227               
228                L->step();
229                Ds->step();                                                     // simulator step
230                //update buffered fdat links
231                for (int i=0; i<Dls_buf.length(); i++){
232                        Dls_buf(i)->store_data(dt);
233                }
234                       
235        }
236
237        L->finalize();
238        // ------------------ End of routine -----------------------------
239
240#ifdef MEX
241        mexlog* mL=dynamic_cast<mexlog*> ( L.get() );
242
243        if ( mL ) { // user wants output!!
244                if ( n_output<1 ) mexErrMsgTxt ( "Wrong number of output variables!" );
245                output[0] = mL->toCell();
246                if (n_output>1) {
247                        mL->_setting_conf().setAutoConvert(true);
248                        output[1]= UImxArray::create_mxArray(mL->_setting_conf().getRoot());
249                }
250        }
251#endif
252        for (int i=0;i<Dlsu.length(); i++){delete Dlsu(i); delete Dlsc(i);}
253}
Note: See TracBrowser for help on using the browser.