dercontroller.h

Go to the documentation of this file.
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 * * 00007 * This program is free software; you can redistribute it and/or modify * 00008 * it under the terms of the GNU General Public License as published by * 00009 * the Free Software Foundation; either version 2 of the License, or * 00010 * (at your option) any later version. * 00011 * * 00012 * This program is distributed in the hope that it will be useful, * 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00015 * GNU General Public License for more details. * 00016 * * 00017 * You should have received a copy of the GNU General Public License * 00018 * along with this program; if not, write to the * 00019 * Free Software Foundation, Inc., * 00020 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 00021 * * 00022 * $Log: dercontroller.h,v $ 00023 * Revision 1.11 2006/12/21 11:44:17 martius 00024 * commenting style for doxygen //< -> ///< 00025 * FOREACH and FOREACHC are macros for collection iteration 00026 * 00027 * Revision 1.10 2006/11/29 16:22:43 martius 00028 * name is a variable of configurable and is used as such 00029 * 00030 * Revision 1.9 2006/10/20 13:32:35 der 00031 * fantasy 00032 * 00033 * Revision 1.8 2006/09/21 16:17:08 der 00034 * *** empty log message *** 00035 * 00036 * Revision 1.7 2006/08/30 13:27:44 martius 00037 * store and restore changed to new Storable interface 00038 * 00039 * Revision 1.6 2006/07/20 17:14:34 martius 00040 * removed std namespace from matrix.h 00041 * storable interface 00042 * abstract model and invertablemodel as superclasses for networks 00043 * 00044 * Revision 1.5 2006/07/17 14:15:47 der 00045 * moved from toselforg to HEAD (wrong commit) 00046 * 00047 * Revision 1.1.2.3 2006/07/17 14:08:51 der 00048 * self-consistent controller with model learning directly form the time loop error 00049 * 00050 * Revision 1.1.2.2 2006/07/14 08:53:14 der 00051 * after cleaning up 00052 * 00053 * Revision 1.1.2.1 2006/07/13 13:01:00 der 00054 * controller with consistent learning from time loop error 00055 * 00056 * 00057 ***************************************************************************/ 00058 #ifndef __DERCONTROLLER_H 00059 #define __DERCONTROLLER_H 00060 00061 #include "invertmotorcontroller.h" 00062 00063 #include <assert.h> 00064 #include <math.h> 00065 00066 #include "matrix.h" 00067 #include "noisegenerator.h" 00068 00069 typedef struct DerControllerConf { 00070 int buffersize; ///< buffersize size of the time-buffer for x,y,eta 00071 double cInit; ///< cInit size of the C matrix to initialised with. 00072 double cNonDiag; ///< cNonDiag is the size of the nondiagonal elements in respect to the diagonal (cInit) ones 00073 bool useS; ///< useS decides whether to use the S matrix in addition to the A matrix 00074 bool someInternalParams; ///< someInternalParams if true only some internal parameters are exported, all otherwise 00075 bool useTeaching; ///< if true, the controller honors the teaching signal 00076 bool useFantasy; ///< if true fantasising is enabled 00077 } DerControllerConf; 00078 00079 /** 00080 * class for robot controller that uses the georg's matrixlib for 00081 * direct matrix inversion for n channels 00082 * (simple one layer networks) 00083 * 00084 * Implements standart parameters: eps, rho, mu, stepnumber4avg, stepnumber4delay 00085 */ 00086 class DerController : public InvertMotorController { 00087 00088 public: 00089 00090 DerController(const DerControllerConf& conf = getDefaultConf()); 00091 virtual void init(int sensornumber, int motornumber); 00092 00093 virtual ~DerController(); 00094 00095 /// returns the number of sensors the controller was initialised with or 0 if not initialised 00096 virtual int getSensorNumber() const { return number_sensors; } 00097 /// returns the mumber of motors the controller was initialised with or 0 if not initialised 00098 virtual int getMotorNumber() const { return number_motors; } 00099 00100 /// performs one step (includes learning). 00101 /// Calulates motor commands from sensor inputs. 00102 virtual void step(const sensor* , int number_sensors, motor* , int number_motors); 00103 00104 /// performs one step without learning. Calulates motor commands from sensor inputs. 00105 virtual void stepNoLearning(const sensor* , int number_sensors, 00106 motor* , int number_motors); 00107 00108 00109 /**** STOREABLE ****/ 00110 virtual bool store(FILE* f) const; 00111 virtual bool restore(FILE* f); 00112 00113 /**** CONFIGURABLE ****/ 00114 virtual std::list<iparamkey> getInternalParamNames() const; 00115 virtual std::list<iparamval> getInternalParams() const; 00116 virtual std::list<ILayer> getStructuralLayers() const; 00117 virtual std::list<IConnection> getStructuralConnections() const; 00118 00119 /**** TEACHING ****/ 00120 virtual void setTeachingMode(bool onOff); 00121 virtual bool getTeachingMode(); 00122 virtual void setMotorTeachingSignal(const motor* teaching, int len); 00123 //void calcCandHUpdatesTeaching(Matrix& C_update, Matrix& H_update, int y_delay); 00124 //void calcCandHUpdates(Matrix& C_update, Matrix& H_update,Matrix& A_update, int y_delay);//Test A 00125 00126 static DerControllerConf getDefaultConf(){ 00127 DerControllerConf c; 00128 c.buffersize = 50; 00129 c.cInit = 1.2; 00130 c.cNonDiag = 0; 00131 c.useS = false; 00132 c.someInternalParams = true; 00133 c.useTeaching = false; 00134 c.useFantasy = true; 00135 return c; 00136 } 00137 00138 void getLastMotors(motor* motors, int len); 00139 00140 protected: 00141 unsigned short number_sensors; 00142 unsigned short number_motors; 00143 00144 matrix::Matrix A; ///< Model Matrix (motors to sensors) 00145 matrix::Matrix S; ///< additional Model Matrix (sensors to sensors) 00146 matrix::Matrix C; ///< Controller Matrix 00147 matrix::Matrix H; ///< Controller Bias 00148 matrix::Matrix B; ///< Model Bias 00149 NoiseGenerator* BNoiseGen; ///< Noisegenerator for noisy bias 00150 NoiseGenerator* YNoiseGen; ///< Noisegenerator for noisy motor values 00151 matrix::Matrix R; ///< C*A 00152 matrix::Matrix RRT; // R*R^T 00153 matrix::Matrix AAT; // (A^T)*A 00154 matrix::Matrix Rm1; ///< R^-1 00155 matrix::Matrix SmallID; ///< small identity matrix in the dimension of R 00156 matrix::Matrix xsi; ///< current output error 00157 double xsi_norm; ///< norm of matrix 00158 double xsi_norm_avg; ///< average norm of xsi (used to define whether Modell learns) 00159 double pain; ///< if the modelling error (xsi) is too high we have a pain signal 00160 matrix::Matrix* x_buffer; 00161 matrix::Matrix* y_buffer; 00162 matrix::Matrix* eta_buffer; 00163 matrix::Matrix zero_eta; // zero initialised eta 00164 matrix::Matrix x_smooth; 00165 00166 matrix::Matrix y_teaching; ///< teaching motor signal 00167 00168 matrix::Matrix x_intern; ///< fantasy sensor values 00169 int fantControl; ///< interval length for fantasising 00170 int fantControlLen; ///< length of fantasy control 00171 int fantReset; ///< number of fantasy control events before reseting internal state 00172 00173 DerControllerConf conf; 00174 00175 /// puts the sensors in the ringbuffer, generate controller values and put them in the 00176 // ringbuffer as well 00177 virtual void fillBuffersAndControl(const sensor* x_, int number_sensors, 00178 motor* y_, int number_motors); 00179 00180 /// calculates the first shift into the motor space useing delayed motor values. 00181 // @param delay 0 for no delay and n>0 for n timesteps delay in the time loop 00182 virtual void calcEtaAndBufferIt(int delay); 00183 /// calculates xsi for the current time step using the delayed y values 00184 // and x delayed by one 00185 // @param delay 0 for no delay and n>0 for n timesteps delay in the time loop 00186 virtual void calcXsi(int delay); 00187 00188 /// learn H,C with motors y and corresponding sensors x 00189 virtual void learnController(); 00190 00191 /// calculates the predicted sensor values 00192 virtual matrix::Matrix model(const matrix::Matrix& x, const matrix::Matrix& y); 00193 00194 /// calculates the Update for C, H and A 00195 // @param y_delay timesteps to delay the y-values. (usually 0) 00196 // Please note that the delayed values are NOT used for the error calculation 00197 // (this is done in calcXsi()) 00198 virtual void calcCandHandAUpdates(matrix::Matrix& C_update, matrix::Matrix& H_update, 00199 matrix::Matrix& A_update, int y_delay);//Test A 00200 /// updates the matrices C, H and A 00201 virtual void updateCandHandA(const matrix::Matrix& C_update, const matrix::Matrix& H_update, 00202 const matrix::Matrix& A_update, double squashSize);//Test A 00203 00204 virtual matrix::Matrix calculateControllerValues(const matrix::Matrix& x_smooth); 00205 00206 /// calculates the city block distance (abs) norm of the matrix. (abs sum of absolutes / size of matrix) 00207 virtual double calcMatrixNorm(const matrix::Matrix& m); 00208 /// calculates the error_factor for either logarithmic (E=ln(e^T*e)) or square (E=sqrt(e^t*e)) error 00209 virtual double calcErrorFactor(const matrix::Matrix& e, bool loga, bool root); 00210 00211 00212 00213 /// squashing function, to protect against too large weight updates 00214 static double squashP(void* d, double z) { 00215 double size = *((double*)d); 00216 return z < -size ? -size : ( z > size ? size : z ); 00217 }; 00218 00219 /// an exact formula for inversion if neuron. 00220 // zeta = (1/(q'(z , xsi)) * xsi 00221 static double q_s(double z, double xsi) { 00222 //double Z = clip(z, -3.0, 3.0) + tanh(xsi); 00223 double Z = clip(z, -2.0, 2.0) + tanh(xsi); 00224 // double Z = clip(z, -3.0, 3.0) + clip(xsi, -1.0, 1.0); 00225 double k=tanh(Z); // approximation with Mittelwertsatz 00226 return /*1/(1+Z*Z);*/ 1 - k*k; 00227 00228 }; 00229 00230 /// an exact formula for q''/q' 00231 static double q_2s_div_s(double z, double xsi) { 00232 // return -2*g(z); 00233 // approximation with Mittelwertsatz (z is clipped) 00234 // return -0.0*g(clip(z, -3.0, 3.0 ) + clip(xsi, -1.0, 1.0));//Test!!!!!!!!!!!1 00235 return -2*g(clip(z, -3.0, 3.0 ) + clip(xsi, -1.0, 1.0)); // approximation with Mittelwertsatz (z is clipped) 00236 00237 /* // the following code seems to make some trouble. (produces NaN or something) */ 00238 /* double s = - fabs(xsi) * sign(z); */ 00239 /* // for s some assumption have to be hold s must be in the inverval (- 2/(e^-2|z|+1), 2/(e^-2|z|+1)) without 0. */ 00240 /* // in case of s=0 we return g''/g' = -2 g */ 00241 /* if(fabs(s) < 0.0001) { */ 00242 /* return -2*g(z); // avoid singularities */ 00243 /* } else{ */ 00244 /* double e_m2z = exp(-2*z); */ 00245 /* double limit = 1.9/(exp(-2*fabs(z)) +1 ); */ 00246 /* s = clip(s, -limit, limit); */ 00247 /* return q_s(z,xsi) * ( ( sqr(1+e_m2z)*s + 2*(1 - sqr(e_m2z)) ) */ 00248 /* / ( sqr(1+e_m2z)*s*s + 2*(1-sqr(e_m2z))*s - 4*e_m2z ) ); */ 00249 /* } */ 00250 }; 00251 00252 /***** CONFIGURABLE ******/ 00253 virtual paramval getParam(const paramkey& key) const{ 00254 if(key == "fantcontrol") return fantControl; 00255 else if(key == "fantcontrollen") return fantControlLen; 00256 else if(key == "fantreset") return fantReset; 00257 else return InvertMotorController::getParam(key); 00258 } 00259 00260 virtual bool setParam(const paramkey& key, paramval val){ 00261 if(key == "fantcontrol") fantControl=(int)val; 00262 else if(key == "fantcontrollen") fantControlLen=(int)val; 00263 else if(key == "fantreset") fantReset=(int)val; 00264 else return InvertMotorController::setParam(key, val); 00265 return true; 00266 } 00267 00268 virtual paramlist getParamList() const{ 00269 paramlist list = InvertMotorController::getParamList(); 00270 if(conf.useFantasy){ 00271 list.push_back(std::pair<paramkey, paramval> ("fantcontrol", fantControl)); 00272 list.push_back(std::pair<paramkey, paramval> ("fantcontrollen", fantControlLen)); 00273 list.push_back(std::pair<paramkey, paramval> ("fantreset", fantReset)); 00274 } 00275 return list; 00276 } 00277 00278 00279 }; 00280 00281 #endif

Generated on Tue Jan 16 02:14:35 2007 for Robotsystem of the Robot Group Leipzig by doxygen 1.3.8