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 * ANY COMMERCIAL USE FORBIDDEN! * 00008 * LICENSE: * 00009 * This work is licensed under the Creative Commons * 00010 * Attribution-NonCommercial-ShareAlike 2.5 License. To view a copy of * 00011 * this license, visit http://creativecommons.org/licenses/by-nc-sa/2.5/ * 00012 * or send a letter to Creative Commons, 543 Howard Street, 5th Floor, * 00013 * San Francisco, California, 94105, USA. * 00014 * * 00015 * This program is distributed in the hope that it will be useful, * 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * 00018 * * 00019 * * 00020 * $Log: invertnchannelcontroller.h,v $ 00021 * Revision 1.21 2008/05/30 11:58:27 martius 00022 * use cmath instead of math.h 00023 * 00024 * Revision 1.20 2008/04/17 14:54:45 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.19 2006/12/11 18:14:14 martius 00032 * delete for BNoise 00033 * delete of buffers 00034 * 00035 * Revision 1.18 2006/08/02 09:31:34 martius 00036 * removed TODO 00037 * 00038 * Revision 1.17 2006/07/20 17:14:35 martius 00039 * removed std namespace from matrix.h 00040 * storable interface 00041 * abstract model and invertablemodel as superclasses for networks 00042 * 00043 * Revision 1.16 2006/07/14 12:23:58 martius 00044 * selforg becomes HEAD 00045 * 00046 * Revision 1.14.6.4 2006/07/10 13:05:16 martius 00047 * NON-COMMERICAL LICENSE added to controllers 00048 * 00049 * Revision 1.14.6.3 2006/07/10 11:59:24 martius 00050 * Matrixlib now in selforg 00051 * no namespace std in header files 00052 * 00053 * Revision 1.14.6.2 2006/01/18 16:48:35 martius 00054 * stored and restore 00055 * 00056 * Revision 1.14.6.1 2005/11/14 17:37:29 martius 00057 * moved to selforg 00058 * 00059 * Revision 1.14 2005/10/27 15:46:38 martius 00060 * inspectable interface is expanded to structural information for network visualiser 00061 * 00062 * Revision 1.13 2005/10/27 15:02:06 fhesse 00063 * commercial use added 00064 * * 00065 * * 00066 ***************************************************************************/ 00067 #ifndef __INVERTNCHANNELCONTROLLER_H 00068 #define __INVERTNCHANNELCONTROLLER_H 00069 00070 #include "invertcontroller.h" 00071 #include "controller_misc.h" 00072 00073 #include <assert.h> 00074 #include <cmath> 00075 00076 #include <selforg/matrix.h> 00077 00078 /** 00079 * class for robot controller that uses the georg's matrixlib for 00080 * direct matrix inversion for n channels 00081 * (simple one layer networks) 00082 * 00083 * Implements standart parameters: eps, rho, mu, stepnumber4avg, stepnumber4delay 00084 */ 00085 class InvertNChannelController : public InvertController { 00086 00087 public: 00088 InvertNChannelController(int _buffersize, bool _update_only_1=false); 00089 virtual void init(int sensornumber, int motornumber, RandGen* randGen = 0); 00090 00091 virtual ~InvertNChannelController(); 00092 00093 /// returns the name of the object (with version number) 00094 virtual paramkey getName() const {return name; } 00095 /// returns the number of sensors the controller was initialised with or 0 if not initialised 00096 virtual int getSensorNumber() const { return number_channels; } 00097 /// returns the mumber of motors the controller was initialised with or 0 if not initialised 00098 virtual int getMotorNumber() const { return number_channels; } 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 00105 /// performs one step without learning. Calulates motor commands from sensor inputs. 00106 virtual void stepNoLearning(const sensor* , int number_sensors, 00107 motor* , int number_motors); 00108 00109 00110 /***** STOREABLE ****/ 00111 /** stores the controller values to a given file. */ 00112 virtual bool store(FILE* f) const; 00113 /** loads the controller values from a given file. */ 00114 virtual bool restore(FILE* f); 00115 00116 // inspectable interface 00117 virtual std::list<iparamkey> getInternalParamNames() const; 00118 virtual std::list<iparamval> getInternalParams() const; 00119 virtual std::list<ILayer> getStructuralLayers() const; 00120 virtual std::list<IConnection> getStructuralConnections() const; 00121 00122 00123 protected: 00124 unsigned short number_channels; 00125 unsigned short buffersize; 00126 bool update_only_1; 00127 00128 matrix::Matrix A; // Model Matrix 00129 matrix::Matrix C; // Controller Matrix 00130 matrix::Matrix h; // Controller Bias 00131 matrix::Matrix L; // Jacobi Matrix 00132 matrix::Matrix* x_buffer; 00133 matrix::Matrix* y_buffer; 00134 int t; 00135 paramkey name; 00136 00137 00138 /* virtual void iteration(double *column, */ 00139 /* double dommy[NUMBER_CHANNELS][NUMBER_CHANNELS], */ 00140 /* double *improvment); */ 00141 00142 virtual double calculateE(const matrix::Matrix& x_delay, const matrix::Matrix& y_delay); 00143 00144 /// learn values h,C 00145 virtual void learn(const matrix::Matrix& x_delay, const matrix::Matrix& y_delay); 00146 00147 virtual void learnmodel( const matrix::Matrix& y_delay); 00148 00149 /// calculate delayed values 00150 virtual matrix::Matrix calculateDelayedValues(const matrix::Matrix* buffer, 00151 unsigned int number_steps_of_delay_); 00152 virtual matrix::Matrix calculateSmoothValues(const matrix::Matrix* buffer, 00153 unsigned int number_steps_for_averaging_); 00154 00155 matrix::Matrix calculateControllerValues(const matrix::Matrix& x_smooth); 00156 00157 // put new value in ring buffer 00158 void putInBuffer(matrix::Matrix* buffer, const matrix::Matrix& vec); 00159 00160 /// neuron transfer function 00161 static double g(double z) 00162 { 00163 return tanh(z); 00164 }; 00165 00166 /// 00167 static double g_s(double z) 00168 { 00169 double k=tanh(z); 00170 return 1.0 - k*k; 00171 // return 1.0 - tanh(z)*tanh(z); 00172 }; 00173 00174 00175 00176 /// squashing function, to protect against to large weight updates 00177 static double squash(double z) 00178 { 00179 return clip(z,-0.1,0.1); 00180 // return z < -0.1 ? -0.1 : ( z > 0.1 ? 0.1 : z ); 00181 //return 0.1 * tanh(10.0 * z); 00182 }; 00183 }; 00184 00185 #endif 00186 00187