proactive.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 * 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 * $Log: proactive.h,v $ 00020 * Revision 1.7 2006/08/04 15:16:13 martius 00021 * documentation 00022 * 00023 * Revision 1.6 2006/07/14 12:23:59 martius 00024 * selforg becomes HEAD 00025 * 00026 * Revision 1.4.6.10 2006/07/10 13:05:16 martius 00027 * NON-COMMERICAL LICENSE added to controllers 00028 * 00029 * Revision 1.4.6.9 2006/07/10 11:59:24 martius 00030 * Matrixlib now in selforg 00031 * no namespace std in header files 00032 * 00033 * Revision 1.4.6.8 2006/02/08 16:19:22 martius 00034 * H-feeding 00035 * 00036 * Revision 1.4.6.7 2006/02/01 18:36:45 martius 00037 * *** empty log message *** 00038 * 00039 * Revision 1.4.6.6 2006/01/31 15:31:21 martius 00040 * use pain signal from model. 00041 * learn h network with context neurons only if pain 00042 * 00043 * Revision 1.4.6.5 2006/01/27 09:37:35 martius 00044 * *** empty log message *** 00045 * 00046 * Revision 1.4.6.4 2006/01/26 18:37:20 martius 00047 * *** empty log message *** 00048 * 00049 * Revision 1.4.6.3 2005/12/15 17:04:39 martius 00050 * min, max and so on are template functions now 00051 * 00052 * Revision 1.4.6.2 2005/11/21 17:05:17 martius 00053 * tau and epsH configurable 00054 * use delayed deltaH for learning the synaptic dynamic network 00055 * 00056 * Revision 1.4.6.1 2005/11/16 11:24:26 martius 00057 * moved to selforg 00058 * 00059 * Revision 1.4 2005/10/06 17:09:29 martius 00060 * switched to stl lists 00061 * a lot of ongoing work 00062 * 00063 * Revision 1.3 2005/09/27 13:58:00 martius 00064 * sensors and motors swapped (for H-Net) 00065 * 00066 * Revision 1.2 2005/09/22 07:30:01 martius 00067 * squashing before learning delta H net 00068 * 00069 * Revision 1.1 2005/09/21 09:28:28 martius 00070 * proactive version of invertmotornstep 00071 * the update of the bias H is done by a synaptic dynamics network 00072 * 00073 * 00074 ***************************************************************************/ 00075 #ifndef __PROACTIVE_H 00076 #define __PROACTIVE_H 00077 00078 #include "invertmotornstep.h" 00079 #include "onelayerffnn.h" 00080 00081 #include <assert.h> 00082 #include <math.h> 00083 00084 #include <selforg/matrix.h> 00085 00086 /** 00087 * robot controller for self-organized behaviour using pro-active elements 00088 * and it is based in InvertMotorNStep. 00089 */ 00090 class ProActive : public InvertMotorNStep { 00091 00092 public: 00093 /** @param numberNonContext number of input channels that are not considered as context inputs 00094 (e.g.\ infrared). 00095 @param tau time window for temporal correlation 00096 @param conf configuration \ref InvertMotorNStepConf 00097 */ 00098 ProActive( unsigned int numberNonContext, unsigned int tau, const InvertMotorNStepConf& conf = getDefaultConf()) 00099 : InvertMotorNStep(conf), synDyn(0.1, 0.0) { 00100 // prepare name; 00101 Configurable::insertCVSInfo(name, "$RCSfile: proactive.h,v $", "$Revision: 1.7 $"); 00102 assert(tau < buffersize); 00103 this->tau = tau; 00104 this->numberNonContext = numberNonContext; 00105 internkeylist = 0; 00106 dampH = 0.0001; 00107 epsH = 0.5; 00108 } 00109 00110 virtual ~ProActive(){ 00111 if (syndyn_buffer){ 00112 delete[] syndyn_buffer; 00113 } 00114 if(internkeylist) free(internkeylist); 00115 } 00116 00117 virtual void init(int sensornumber, int motornumber){ 00118 assert( numberNonContext <= (unsigned int) sensornumber); 00119 number_all_sensors = sensornumber; 00120 InvertMotorNStep::init(numberNonContext, motornumber); 00121 00122 int synDynInputNumber = (sensornumber - numberNonContext); // + motornumber 00123 synDyn.init(synDynInputNumber, motornumber); 00124 syndyn_buffer = new matrix::Matrix[buffersize]; 00125 00126 for (unsigned int k = 0; k < buffersize; k++) { 00127 syndyn_buffer[k].set(synDynInputNumber,1); 00128 } 00129 H_delta.set(motornumber,1); 00130 H_delta_net.set(motornumber,1); 00131 00132 H_orig.set(motornumber,1); 00133 H_context.set(motornumber,1); 00134 h_context_norm_avg=0.01; 00135 00136 if(internkeylist) free(internkeylist); 00137 internkeylist=0; 00138 } 00139 00140 virtual void step(const sensor* x_, int number_sensors, motor* y_, int number_motors){ 00141 // call InvertMotorNStep just with the non-context sensors 00142 // column vector with context sensor values 00143 x_context.set(number_all_sensors - numberNonContext, 1, x_ + numberNonContext); 00144 InvertMotorNStep::step(x_, numberNonContext, y_, number_motors); 00145 } 00146 00147 /// performs one step without learning. Calulates motor commands from sensor inputs. 00148 virtual void stepNoLearning(const sensor* x_, int number_sensors, 00149 motor* y_, int number_motors){ 00150 x_context.set(number_all_sensors - numberNonContext, 1, x_ + numberNonContext); // column vector with context sensor values 00151 // time is increased 00152 InvertMotorNStep::stepNoLearning(x_, numberNonContext, y_, number_motors); 00153 t--; 00154 bufferSynDynInput(); 00155 t++; 00156 } 00157 00158 /// return the name of the object (with version number) Hint: use insertCVSInfo from Configurable 00159 virtual paramkey getName() const { return name; } 00160 00161 virtual list<iparamkey> getInternalParamNames() const { 00162 list<iparamkey> keylist = InvertMotorNStep::getInternalParamNames(); 00163 if(conf.someInternalParams){ 00164 keylist += store4x4AndDiagonalFieldNames(synDyn.getWeights(), "HDW"); 00165 }else{ 00166 keylist += storeMatrixFieldNames(synDyn.getWeights(), "HDW"); 00167 } 00168 keylist += storeMatrixFieldNames(synDyn.getBias(), "HDB"); 00169 keylist += storeMatrixFieldNames(H_delta, "HD"); 00170 keylist += storeMatrixFieldNames(H_delta_net, "HDN"); 00171 keylist += storeVectorFieldNames(syndyn_buffer[0], "hinput"); 00172 keylist += storeVectorFieldNames(H_orig, "H_orig"); 00173 return keylist; 00174 } 00175 00176 virtual list<iparamval> getInternalParams() const { 00177 list<iparamval> l = InvertMotorNStep::getInternalParams(); 00178 if(conf.someInternalParams){ 00179 l += store4x4AndDiagonal(synDyn.getWeights()); 00180 }else{ 00181 l += synDyn.getWeights().convertToList(); 00182 } 00183 l += synDyn.getBias().convertToList(); 00184 l += H_delta.convertToList(); 00185 l += H_delta_net.convertToList(); 00186 l += syndyn_buffer[(t+buffersize-tau)%buffersize].convertToList(); 00187 l += H_orig.convertToList(); 00188 00189 return l; 00190 } 00191 00192 virtual paramval getParam(const paramkey& key) const{ 00193 if( key == "epsH") return epsH; 00194 else if( key == "tau") return tau; 00195 else if( key == "dampH") return dampH; 00196 else { 00197 paramval v = synDyn.getParam(key); 00198 if( v!=0.0) return v; 00199 else return InvertMotorNStep::getParam(key); 00200 } 00201 } 00202 00203 virtual bool setParam(const paramkey& key, paramval val){ 00204 if(key == "epsH") epsH = val; 00205 else if(key == "tau") tau = (unsigned int)val; 00206 else if(key == "dampH") dampH = val; 00207 else if(synDyn.setParam(key, val)) return true; 00208 else return InvertMotorNStep::setParam(key, val); 00209 return true; 00210 } 00211 00212 virtual paramlist getParamList() const{ 00213 paramlist keylist = InvertMotorNStep::getParamList(); 00214 keylist += pair<paramkey, paramval> (string("epsH"), epsH); 00215 keylist += pair<paramkey, paramval> (string("tau"), tau); 00216 keylist += pair<paramkey, paramval> (string("dampH"), dampH); 00217 keylist += synDyn.getParamList(); 00218 return keylist; 00219 } 00220 00221 static InvertMotorNStepConf getDefaultConf(){ 00222 InvertMotorNStepConf c; 00223 c.buffersize = 10; 00224 c.cInit = 0.1; 00225 c.useS = true; 00226 c.someInternalParams = true; 00227 return c; 00228 } 00229 00230 protected: 00231 00232 virtual void bufferSynDynInput(){ 00233 //const matrix::Matrix z = C * x_smooth + H; 00234 const matrix::Matrix& y = y_buffer[t% buffersize]; 00235 // first the postsynaptic potential and then the context sensors and then the non-context sensors 00236 // matrix::Matrix hinput = z.above(x_context*y.val(0,0)); // column vector with z above x_context 00237 // const matrix::Matrix& hinput = z.above(x_context); // column vector with z above x_context 00238 const matrix::Matrix& hinput = x_context; 00239 // put new sensor vector in ring buffer sensor_buffer (all sensors) 00240 putInBuffer(syndyn_buffer, hinput); 00241 } 00242 00243 /// calculates xsi for the current time step using the delayed y values 00244 // overloaded version which incorporates time smoothing 00245 virtual void calcXsi(int delay){ 00246 InvertMotorNStep::calcXsi(delay); 00247 } 00248 00249 /// overloaded version which includes the synaptic dynamics network 00250 /// updates the matrix C and H 00251 virtual void updateCandH(const matrix::Matrix& C_update, const matrix::Matrix& H_update, double squashSize){ 00252 bufferSynDynInput(); 00253 00254 // the C-update stays as it is. 00255 C += C_update.mapP(&squashSize, squashP); 00256 // // the H-update is also applied, but there is another term see below 00257 // H += H_update.mapP(&squashSize, squashP); 00258 00259 // for H-update we use an additional network, which learns the update 00260 // in case of paint. 00261 // We use delayed y and delayed x values so that the current 00262 // error can be assoziated with previous motor commands. 00263 matrix::Matrix C_update_delay(C.getM(), C.getN()); 00264 matrix::Matrix H_update_delay(H.getM(), H.getN()); 00265 matrix::Matrix hinput_delay = syndyn_buffer[(t - tau) % buffersize]; 00266 if(pain!=0){ 00267 // pain learning 00268 calcCandHUpdates(C_update_delay, H_update_delay, tau); 00269 double squashS=1; 00270 H_delta = H_update_delay.mapP(&squashS, squashP); 00271 synDyn.learn(hinput_delay, H_delta); 00272 } 00273 00274 // apply the output of the network to H (use current inputs) 00275 const matrix::Matrix& hinput = syndyn_buffer[t % buffersize]; 00276 H_delta_net = synDyn.process(hinput); 00277 synDyn.damp(dampH); 00278 00279 H_context = H_delta_net * epsH; 00280 double h_context_norm = calcMatrixNorm(H_context); 00281 double decay=0.0001; 00282 h_context_norm_avg = h_context_norm_avg*(1-decay) + h_context_norm*decay; 00283 00284 00285 if(h_context_norm < h_context_norm_avg * 5){ 00286 // normal H dynamic 00287 H_orig += H_update.mapP(&squashSize, squashP); 00288 }else{ 00289 cerr << "pla"; 00290 } 00291 00292 H = H_orig + H_context; 00293 00294 00295 00296 } 00297 00298 protected: 00299 OneLayerFFNN synDyn; 00300 00301 matrix::Matrix* syndyn_buffer; 00302 matrix::Matrix x_context; 00303 matrix::Matrix H_context; 00304 double h_context_norm_avg; 00305 matrix::Matrix H_orig; 00306 paramkey* internkeylist; 00307 00308 unsigned int tau; 00309 unsigned int numberNonContext; 00310 unsigned int number_all_sensors; 00311 double dampH; 00312 double epsH; 00313 00314 matrix::Matrix H_delta; 00315 matrix::Matrix H_delta_net; 00316 00317 }; 00318 00319 #endif

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