00001 /*************************************************************************** 00002 * Copyright (C) 2005 by Robot Group Leipzig * 00003 * martius@informatik.uni-leipzig.de * 00004 * fhesse@informatik.uni-leipzig.de * 00005 * der@informatik.uni-leipzig.de * 00006 * frankguettler@gmx.de * 00007 * * 00008 * This program is free software; you can redistribute it and/or modify * 00009 * it under the terms of the GNU General Public License as published by * 00010 * the Free Software Foundation; either version 2 of the License, or * 00011 * (at your option) any later version. * 00012 * * 00013 * This program is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00016 * GNU General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU General Public License * 00019 * along with this program; if not, write to the * 00020 * Free Software Foundation, Inc., * 00021 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 00022 * * 00023 * $Log: abstractmulticontroller.h,v $ 00024 * Revision 1.5 2008/04/17 14:54:44 martius 00025 * randomGen added, which is a random generator with long period and an 00026 * internal state. Each Agent has an instance and passed it to the controller 00027 * and the wiring. This is good for 00028 * a) repeatability on agent basis, 00029 * b) parallel execution as done in ode_robots 00030 * 00031 * Revision 1.4 2007/12/12 10:26:13 der 00032 * MI: calculation of H(X) and H(Y|X) added 00033 * 00034 * Revision 1.3 2007/04/19 13:48:20 robot3 00035 * inserted new MI update function - needs O(1) instead of O(n^2) 00036 * 00037 * Revision 1.2 2007/03/22 11:35:12 der 00038 * corrected some bugs 00039 * 00040 * Revision 1.1 2007/03/22 08:11:44 robot3 00041 * abstract class for having multiple controllers for one Agent. See 00042 * OneActiveMultiPassiveController for example. 00043 * 00044 00045 * * 00046 ***************************************************************************/ 00047 #ifndef __ABSTRACTMULTICONTROLLER_H 00048 #define __ABSTRACTMULTICONTROLLER_H 00049 00050 #include "abstractcontrolleradapter.h" 00051 00052 /** 00053 * Abstract class (interface) for using multiple controller. 00054 * A controller gets a number of input sensor values each timestep 00055 * and has to generate a number of output motor values 00056 * 00057 * 00058 * This is an abstract class, it's useful for implementing multicontrollers such as the 00059 * OneActiveMultiPassiveController, which can be used with all Controllers. 00060 * 00061 * Any MulitController implementing this class should overwrite the methods step(...) and 00062 * stepNoLearning(...). 00063 */ 00064 class AbstractMultiController : public AbstractControllerAdapter { 00065 public: 00066 00067 /// contructor (hint: use $ID$ for revision) 00068 AbstractMultiController(AbstractController* controller, std::string controllerName) 00069 : AbstractControllerAdapter(controller) { 00070 this->controllerNameList.push_back(controllerName); 00071 } 00072 00073 virtual ~AbstractMultiController() {} 00074 00075 /** 00076 * Adds a passive controller to this MultiController. If the Agent calls step(..) 00077 * or stepNoLearning(..), the MultiController calls not only the active controllers 00078 * step(...) but also the step(...) of all the passive controllers. (same for 00079 * stepNoLearning(..) ). 00080 * 00081 * Note: The initialisation of the MultiController with init(sensornumber, motornumber) 00082 * must be called after all passive controllers are added, otherwise you must 00083 * init the passive controller yourself (not recommended and can generate problems) 00084 */ 00085 virtual void addPassiveController(AbstractController* passiveController, std::string name) { 00086 if (passiveController!=0) { 00087 controllerList.push_back(passiveController); 00088 controllerNameList.push_back(name); 00089 } // otherwise return 00090 } 00091 00092 /****************************************************************************/ 00093 /* AbstractMultiController should implement the following classes: */ 00094 /* AbstractController, Configurable, Inspectable, Storeable */ 00095 /****************************************************************************/ 00096 00097 00098 /****************************************************************************/ 00099 /* BEGIN methods of AbstractController */ 00100 /****************************************************************************/ 00101 00102 00103 /** initialisation of the controller with the given sensor/ motornumber 00104 * Must NORMALLY be called before use. For all multicontroller 00105 * call first AbstractMultiController::init(sensornumber,motornumber) 00106 * if you overwrite this method 00107 */ 00108 virtual void init(int sensornumber, int motornumber, RandGen* randGen = 0){ 00109 AbstractControllerAdapter::init( sensornumber,motornumber); 00110 // init the other controllers 00111 for(std::list<AbstractController*>::iterator i=controllerList.begin(); i != controllerList.end(); i++){ 00112 if (*i) (*i)->init(sensornumber,motornumber); 00113 } 00114 } 00115 00116 /** performs one step (includes learning). 00117 Calculates motor commands from sensor inputs. 00118 @param sensors sensors inputs scaled to [-1,1] 00119 @param sensornumber length of the sensor array 00120 @param motors motors outputs. MUST have enough space for motor values! 00121 @param motornumber length of the provided motor array 00122 */ 00123 virtual void step(const sensor* sensors, int sensornumber, 00124 motor* motors, int motornumber)=0; 00125 00126 /** performs one step without learning. 00127 @see step 00128 */ 00129 virtual void stepNoLearning(const sensor* sensors , int sensornumber, 00130 motor* motors, int motornumber)=0; 00131 00132 00133 /****************************************************************************/ 00134 /* END methods of AbstractController */ 00135 /****************************************************************************/ 00136 00137 /****************************************************************************/ 00138 /* BEGIN methods of Configurable */ 00139 /****************************************************************************/ 00140 00141 00142 00143 /****************************************************************************/ 00144 /* END methods of Configurable */ 00145 /****************************************************************************/ 00146 00147 /****************************************************************************/ 00148 /* BEGIN methods of Inspectable */ 00149 /****************************************************************************/ 00150 00151 /** The list of the names of all internal parameters given by getInternalParams(). 00152 The naming convention is "v[i]" for vectors 00153 and "A[i][j]" for matrices, where i, j start at 0. 00154 @return: list of keys 00155 */ 00156 virtual iparamkeylist getInternalParamNames() const { 00157 std::list<iparamkey> keyList; 00158 // return all parameters from the other controllers 00159 00160 // get the name of the controller 00161 std::list<std::string>::const_iterator cname=controllerNameList.begin(); 00162 // first active controller 00163 std::list<iparamkey> controllerKeyList = controller->getInternalParamNames(); 00164 for( std::list<iparamkey>::iterator key=controllerKeyList.begin();key!=controllerKeyList.end();key++ ) 00165 keyList+= (*cname) + "" + (*key); 00166 00167 // now the passive controllers 00168 for(std::list<AbstractController*>::const_iterator c=controllerList.begin(); c!= controllerList.end(); c++){ 00169 if (*c) { 00170 cname++; 00171 controllerKeyList = (*c)->getInternalParamNames(); 00172 for( std::list<iparamkey>::iterator key=controllerKeyList.begin();key!=controllerKeyList.end();key++ ) 00173 keyList+= (*cname) + "" + (*key); 00174 } 00175 } 00176 return keyList; 00177 } 00178 00179 /** @return: list of values 00180 */ 00181 virtual iparamvallist getInternalParams() const { 00182 // return all parameters from the other controllers 00183 // return params from multicontroller itself 00184 std::list<iparamval> valList; 00185 // return all parameters from the other controllers 00186 00187 // first active controller 00188 valList+= controller->getInternalParams(); 00189 00190 // now the passive controllers 00191 for(std::list<AbstractController*>::const_iterator c=controllerList.begin(); c!= controllerList.end(); c++) { 00192 valList+=(*c)->getInternalParams(); 00193 } 00194 //int j=0; 00195 return valList; 00196 } 00197 00198 /****************************************************************************/ 00199 /* END methods of Inspectable */ 00200 /****************************************************************************/ 00201 00202 /****************************************************************************/ 00203 /* BEGIN methods of Storeable */ 00204 /****************************************************************************/ 00205 00206 /** stores the object to the given file stream (binary). 00207 */ 00208 virtual bool store(FILE* f) const { 00209 return controller->store(f); 00210 // store the other controllers 00211 // store values from multicontroller itself 00212 } 00213 00214 /** loads the object from the given file stream (binary). 00215 */ 00216 virtual bool restore(FILE* f) { 00217 return controller->restore(f); 00218 // restore the other controllers 00219 // restore values from multicontroller itself 00220 } 00221 00222 /****************************************************************************/ 00223 /* END methods of Storeable */ 00224 /****************************************************************************/ 00225 00226 protected: 00227 // The AbstractController* controller is defined in AbstractControllerAdapter! 00228 std::list<AbstractController*> controllerList; // stores the other controllers 00229 std::list<std::string> controllerNameList; // stores the names of the controllers 00230 }; 00231 00232 #endif