Robot Simulator of the Robotics Group for Self-Organization of Control  0.8.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
invert3channelcontroller.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2011 by *
3  * Georg Martius <georg dot martius at web dot de> *
4  * Frank Hesse <frank at nld dot ds dot mpg dot de> *
5  * Ralf Der <ralfder at mis dot mpg dot de> *
6  * *
7  * ANY COMMERCIAL USE FORBIDDEN! *
8  * LICENSE: *
9  * This work is licensed under the Creative Commons *
10  * Attribution-NonCommercial-ShareAlike 2.5 License. To view a copy of *
11  * this license, visit http://creativecommons.org/licenses/by-nc-sa/2.5/ *
12  * or send a letter to Creative Commons, 543 Howard Street, 5th Floor, *
13  * San Francisco, California, 94105, USA. *
14  * *
15  * This program is distributed in the hope that it will be useful, *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
18  * *
19  ***************************************************************************/
20 
21 #ifndef __INVERT3CHANNELCONTROLLER_H
22 #define __INVERT3CHANNELCONTROLLER_H
23 
24 #include "invertcontroller.h"
25 
26 #include <cassert>
27 #include <cmath>
28 
29 
30 /**
31  * class for robot controller that use naglaa's direct matrix inversion for n channels
32  * (simple one layer networks)
33  *
34  * Implements standart parameters: eps, rho, mu, stepnumber4avg, stepnumber4delay
35  */
36 template <int NUMBER_CHANNELS, int BUFFER_SIZE=2> class Invert3ChannelController : public InvertController {
37 
38 public:
39 
40  /*
41  Invert3ChannelController();
42 
43  //virtual ~Invert3ChannelController(){}
44 
45 
46  /// performs one step (includes learning). Calulates motor commands from sensor inputs.
47  virtual void step(const sensor*, motor*);
48 
49  /// performs one step without learning. Calulates motor commands from sensor inputs.
50  virtual void stepNoLearning(const sensor*, motor*);
51  */
52 
53 
54  //protected:
55 public:
56  double A[NUMBER_CHANNELS][NUMBER_CHANNELS]; ///< model matrix
57  double C[NUMBER_CHANNELS][NUMBER_CHANNELS]; ///< controller matrix
58  double h[NUMBER_CHANNELS]; ///< bias vector
59 
60  double x_buffer[BUFFER_SIZE][NUMBER_CHANNELS]; ///< buffer for input values, x[t%buffersize]=actual value, x[(t-1+buffersize)%buffersize]=x(t-1)
61  double y_buffer[BUFFER_SIZE][NUMBER_CHANNELS]; ///< buffer for output values, y[t%buffersize]=actual value(if already calculated!), y[(t-1+buffersize)%buffersize]=y(t-1)
62 
63  double xsi4E[NUMBER_CHANNELS];
64  double xsi4Model[NUMBER_CHANNELS];
65 
66  int t; ///< number of steps, needed for ringbuffer x_buffer
67 
68 
69 
70 
71 
72  /*
73  virtual void inverseMatrix(double Q[NUMBER_CHANNELS][NUMBER_CHANNELS], double Q_1[NUMBER_CHANNELS][NUMBER_CHANNELS]);
74 
75  virtual double calculateE(double *x_delay, double *y_delay);
76 
77  /// learn values h,C //,A
78  virtual void learn(double *x_delay, double *y_delay);
79 
80  /// learn model parameter (matrix A) by gradient descent
81  virtual void learnModel(double *x_actual, double *y_effective);
82 
83 
84  /// calculate delayed values
85  virtual void calculateDelayedValues(double source[BUFFER_SIZE][NUMBER_CHANNELS], int number_steps_of_delay_, double *target);
86 
87  virtual void calculateSmoothValues(double source[BUFFER_SIZE][NUMBER_CHANNELS], int number_steps_for_averaging_, double *target);
88 
89  /// calculate controller ouptus
90  virtual void calculateControllerValues(double *x_smooth, double *y);
91 
92  // put new value in ring buffer
93  virtual void putInBuffer(double buffer[BUFFER_SIZE][NUMBER_CHANNELS], double *values);
94 
95  */
96  /// neuron transfer function
97  virtual double g(double z)
98  {
99  return tanh(z);
100  };
101 
102 
103 
104  ///
105  virtual double g_s(double z)
106  {
107  return 1.0 - tanh(z) * tanh(z);
108  };
109 
110 
111 
112  /// squashing function, to protect against to large weight updates
113  virtual double squash(double z)
114  {
115  return 0.1 * tanh(10.0 * z);
116  };
117 
118 
119  //template <int NUMBER_CHANNELS, int BUFFER_SIZES>
120  // Invert3ChannelController<int NUMBER_CHANNELS, int BUFFER_SIZES>::
122 
123  t=0;
124 
125  for (int i = 0; i < NUMBER_CHANNELS; i++)
126  {
127  h[i] = 0.0;
128  for (int j = 0; j < NUMBER_CHANNELS; j++)
129  {
130  if (i == j)
131  {
132  A[i][j] = 1.0;
133  C[i][j] = 0.1;
134  }
135  else
136  {
137  A[i][j] = 0.0;
138  C[i][j] = 0.0;
139  }
140  }
141  }
142  for (int i = 0; i < NUMBER_CHANNELS; i++)
143  {
144  for (int k = 0; k < BUFFER_SIZE; k++)
145  {
146  x_buffer[k][i] = 0;
147  y_buffer[k][i] = 0;
148  }
149  }
150 
151  /* // print initial values
152  std::cout<<"Constructor of RobotLearnControl:"<<std::endl;
153  std::cout<<"init: epsilon="<<eps<<std::endl;
154  std::cout<<"init: rho="<<rho<<std::endl;
155  std::cout<<"init: stepnumber4delay="<<stepnumber4delay<<std::endl;
156  std::cout<<"init: stepnumber4avg="<<stepnumber4avg<<std::endl;
157  std::cout<<"init: delta="<<delta<<std::endl;
158  std::cout<<"init: m (for calculation of E)="<<m<<std::endl;
159  */
160  };
161 
162  /// performs one step (includes learning). Calulates motor commands from sensor inputs.
163  virtual void step(const sensor* x_, int sensornumber,
164  motor* y_, int motornumber) {
165  double x_smooth[NUMBER_CHANNELS];
166  double x_effective[NUMBER_CHANNELS];
167  double y_effective[NUMBER_CHANNELS];
168  for (int i = 0; i < NUMBER_CHANNELS; i++)
169  {
170  x_smooth[i] = 0.0;
171  x_effective[i] = 0.0;
172  y_effective[i] = 0.0;
173  }
174 
175  // put new input value in ring buffer x_buffer
176  putInBuffer(x_buffer, x_);
177 
178  // averaging over the last stepnumber4avg values of x_buffer
179  calculateSmoothValues(x_buffer, stepnumber4avg, x_smooth);
180 
181  // calculate controller values based on smoothed input values
182  calculateControllerValues(x_smooth, y_);
183 
184  // put new output value in ring buffer y_buffer
185  putInBuffer(y_buffer, y_);
186 
187  // calculate effective input/output, which is (actual-stepnumber4delay) element of buffer
188  calculateDelayedValues(x_buffer, stepnumber4delay, x_effective);
189  calculateDelayedValues(y_buffer, stepnumber4delay, y_effective);
190 
191  // learn controller with effective input/output
192  learn(x_, x_effective, y_effective);
193 
194  // learn model with actual input and effective output (that produced the actual input)
195  learnModel(x_, y_effective);
196 
197  // update step counter
198  t++;
199  };
200 
201 
202  /// performs one step without learning. Calulates motor commands from sensor inputs.
203  virtual void stepNoLearning(const sensor* x_, int sensornumber,
204  motor* y_, int motornumber){
205  double x_smooth[NUMBER_CHANNELS];
206  for (int i = 0; i < NUMBER_CHANNELS; i++)
207  {
208  x_smooth[i] = 0.0;
209  }
210 
211 
212  // put new input value in ring buffer x_buffer
213  putInBuffer(x_buffer, x_);
214 
215  // averaging over the last stepnumber4avg values of x_buffer
216  calculateSmoothValues(x_buffer, stepnumber4avg, x_smooth);
217 
218  // calculate controller values based on smoothed input values
219  calculateControllerValues(x_smooth, y_);
220 
221  // put new output value in ring buffer y_buffer
222  putInBuffer(y_buffer, y_);
223 
224  // update step counter
225  t++;
226  };
227 
228 
229 protected:
230  virtual void inverseMatrix(double Q[NUMBER_CHANNELS][NUMBER_CHANNELS], double Q_1[NUMBER_CHANNELS][NUMBER_CHANNELS]){
231  // Berechne Inverse von Q
232 
233  // only if NUMBER_CHANNELS<4
234  assert(NUMBER_CHANNELS<4);
235  if (NUMBER_CHANNELS==2){
236 
237  double det = Q[0][0] * Q[1][1] - Q[0][1] * Q[1][0];
238  Q_1[0][0] = Q[1][1] / det;
239  Q_1[1][1] = Q[0][0] / det;
240  Q_1[0][1] = -Q[0][1] / det;
241  Q_1[1][0] = -Q[1][0] / det;
242 
243  }
244 
245 
246  if (NUMBER_CHANNELS==3){
247 
248  double Q_adjoint[NUMBER_CHANNELS][NUMBER_CHANNELS] ;
249  double detQ=0 ;
250 
251  //calculate the inverse of Q
252  Q_adjoint[0][0]=Q[1][1]*Q[2][2]-Q[1][2]*Q[2][1] ;
253  Q_adjoint[0][1]=(Q[1][2]*Q[2][0]-Q[1][0]*Q[2][2]) ;
254  Q_adjoint[0][2]=Q[1][0]*Q[2][1]-Q[1][1]*Q[2][0] ;
255  Q_adjoint[1][0]=(Q[2][1]*Q[0][2]-Q[0][1]*Q[2][2]) ;
256  Q_adjoint[1][1]=Q[0][0]*Q[2][2]-Q[0][2]*Q[2][0] ;
257  Q_adjoint[1][2]=(Q[0][1]*Q[2][0]-Q[0][0]*Q[2][1]) ;
258  Q_adjoint[2][0]=Q[0][1]*Q[1][2]-Q[1][1]*Q[0][2] ;
259  Q_adjoint[2][1]=(Q[1][0]*Q[0][2]-Q[0][0]*Q[1][2]) ;
260  Q_adjoint[2][2]=Q[0][0]*Q[1][1]-Q[0][1]*Q[1][0] ;
261  detQ=Q[0][0]*Q_adjoint[0][0]+Q[0][1]*Q_adjoint[0][1]+Q[0][2]*Q_adjoint[0][2] ;
262  for(int i=0; i<NUMBER_CHANNELS; i++){
263  for(int j=0; j<NUMBER_CHANNELS; j++) {
264  Q_1[i][j]=(Q_adjoint[j][i])/detQ ;
265  }
266  }
267  }
268  };
269 
270 
271  virtual double calculateE(const double *x_, const double *x_delay, const double *y_delay) {
272  double L[NUMBER_CHANNELS][NUMBER_CHANNELS];
273  double Q[NUMBER_CHANNELS][NUMBER_CHANNELS];
274  double Q_1[NUMBER_CHANNELS][NUMBER_CHANNELS];
275  double z[NUMBER_CHANNELS];
276 
277 
278  // Calculate z based on the delayed inputs since the present input x is
279  // produced by the outputs tau time steps before
280  // which on their hand are y = K(x_D)
281  // due to the delay in the feed back loop.
282 
283  for (int i = 0; i < NUMBER_CHANNELS; i++)
284  {
285  z[i] = h[i];
286  for (int j = 0; j < NUMBER_CHANNELS; j++)
287  {
288  z[i] += C[i][j] * x_delay[j];
289  }
290  }
291 
292  // Berechne Matrix L
293  for (int i = 0; i < NUMBER_CHANNELS; i++)
294  {
295  for (int j = 0; j < NUMBER_CHANNELS; j++)
296  {
297  L[i][j] = 0.0;
298  for (int k = 0; k < NUMBER_CHANNELS; k++)
299  {
300  L[i][j] += A[i][k] * g_s(z[k]) * C[k][j];
301  }
302  }
303  }
304 
305  // Berechne Q=LL^T
306  for (int i = 0; i < NUMBER_CHANNELS; i++)
307  {
308  for (int j = 0; j < NUMBER_CHANNELS; j++)
309  {
310  Q[i][j] = 0.0;
311  for (int k = 0; k < NUMBER_CHANNELS; k++)
312  {
313  Q[i][j] += L[i][k] * L[j][k];
314  }
315  if (i == j)
316  Q[i][j] += rho / NUMBER_CHANNELS; // Regularisation
317  }
318  }
319 
320  // Berechne Inverse von Q
321  inverseMatrix(Q, Q_1);
322 
323  // Berechne xsi
324  for (int i = 0; i < NUMBER_CHANNELS; i++)
325  {
326  xsi4E[i] = x_[i];
327  for (int j = 0; j < NUMBER_CHANNELS; j++)
328  {
329  xsi4E[i] -= A[i][j] * y_delay[j]; // using old y value -> no influence of changes (adding delta) in controller
330  // very very strange!!!!
331  //xsi4E[i] -= A[i][j] * g(z[j]); // using recalculating y -> influence of changes (adding delta) in controller
332  }
333  }
334  double E = 0;
335  for (int i = 0; i < NUMBER_CHANNELS; i++)
336  {
337  for (int j = 0; j < NUMBER_CHANNELS; j++)
338  {
339  E += xsi4E[i] * Q_1[i][j] * xsi4E[j];
340  }
341  }
342 
343  double E_s=0;
344  for (int i = 0; i < NUMBER_CHANNELS; i++)
345  {
346  for (int j = 0; j < NUMBER_CHANNELS; j++)
347  {
348  E_s += (A[i][j]*g(z[j]) - x_[i]) * (A[i][j]*g(z[j]) - x_[i]);
349  }
350  }
351 
352  E=(1-m)*E+ m*E_s;
353  return (E);
354 
355  };
356 
357 
358  virtual void learn(const double *x_, const double *x_delay, const double *y_delay)
359  {
360  // double A_update[NUMBER_CHANNELS][NUMBER_CHANNELS];
361  double C_update[NUMBER_CHANNELS][NUMBER_CHANNELS];
362  double h_update[NUMBER_CHANNELS];
363 
364  double E_0 = calculateE(x_,x_delay, y_delay);
365 
366  // calculate updates for h,C,A
367  for (int i = 0; i < NUMBER_CHANNELS; i++)
368  {
369  h[i] += delta;
370  h_update[i] = -eps * (calculateE(x_,x_delay, y_delay) - E_0) / delta;
371  h[i] -= delta;
372  for (int j = 0; j < NUMBER_CHANNELS; j++)
373  {
374  C[i][j] += delta;
375  C_update[i][j] = -eps * (calculateE(x_,x_delay, y_delay) - E_0) / delta;
376  C[i][j] -= delta;
377  //A[i][j] += delta;
378  //A_update[i][j] = -eps * a_factor * (calculateE(x_delay, y_delay) - E_0) / delta;
379  //A[i][j] -= delta;
380  }
381  }
382 
383  // apply updates to h,C,A
384  for (int i = 0; i < NUMBER_CHANNELS; i++)
385  {
386  h[i] += squash(h_update[i]);
387  for (int j = 0; j < NUMBER_CHANNELS; j++)
388  {
389  C[i][j] += squash(C_update[i][j]);
390  //A[i][j] += squash(A_update[i][j]);
391  }
392  }
393  };
394 
395 
396  virtual void learnModel(const double *x_actual, double *y_effective){
397  /* double z[N_output];
398  for(int i=0; i<N_output; i++){
399  z[i]=h[i];
400  for(int j=0; j<N_input; j++) {
401  z[i]+=C[i][j]*x_D[j];
402  }
403  }
404  */
405  // Berechne xsi
406  for(int i=0; i<NUMBER_CHANNELS; i++){
407  xsi4Model[i]=x_actual[i];
408  for(int j=0; j<NUMBER_CHANNELS; j++){
409  xsi4Model[i]-= A[i][j]*y_effective[j];
410  }
411  }
412 
413  for(int i=0; i<NUMBER_CHANNELS; i++){
414  for (int j=0; j<NUMBER_CHANNELS; j++){
415  A[i][j]+=squash( (factor_a*eps*0.2) *xsi4Model[i] * y_effective[j]) ;
416  }
417  }
418  };
419 
420 
421 
422 
423 
424  /// calculate delayed values
425  virtual void calculateDelayedValues(double source[BUFFER_SIZE][NUMBER_CHANNELS], paramval number_steps_of_delay_, double *target)
426  {
427  // number_steps_of_delay_ must not be larger than BUFFER_SIZE
428  assert ((int)number_steps_of_delay_ < BUFFER_SIZE);
429 
430  // get delayed value from ring buffer
431 
432  for (int i = 0; i < NUMBER_CHANNELS; i++)
433  {
434  target[i] = source[(t - (int)number_steps_of_delay_ + BUFFER_SIZE) % BUFFER_SIZE][i];
435  }
436  };
437 
438  virtual void calculateSmoothValues(double source[BUFFER_SIZE][NUMBER_CHANNELS], paramval number_steps_for_averaging_, double *target)
439  {
440  // number_steps_for_averaging_ must not be larger than BUFFER_SIZE
441  assert ((int)number_steps_for_averaging_ <= BUFFER_SIZE);
442 
443  for (int i = 0; i < NUMBER_CHANNELS; i++)
444  {
445  target[i] = 0.0;
446  for (int k = 0; k < (int)number_steps_for_averaging_; k++)
447  {
448  target[i] += source[(t - k + BUFFER_SIZE) % BUFFER_SIZE][i]/ (double) (number_steps_for_averaging_);
449  }
450  }
451  };
452 
453 
454 
455  /// calculate controller ouptus
456  virtual void calculateControllerValues(double *x_smooth, double *y)
457  {
458  double z[NUMBER_CHANNELS];
459 
460  for (int i = 0; i < NUMBER_CHANNELS; i++)
461  {
462  z[i] = h[i];
463  for (int j = 0; j < NUMBER_CHANNELS; j++)
464  {
465  z[i] += C[i][j] * x_smooth[j];
466  }
467  y[i] = g(z[i]);
468  }
469  };
470 
471 
472  // put new value in ring buffer
473  virtual void putInBuffer(double buffer[BUFFER_SIZE][NUMBER_CHANNELS], const double *values){
474  for (int i = 0; i < NUMBER_CHANNELS; i++)
475  {
476  buffer[(t+BUFFER_SIZE)% BUFFER_SIZE][i] = values[i];
477  }
478  };
479 
480 
481 
482  virtual int getInternalParamNames(paramkey*& keylist){
483  keylist=(paramkey*)malloc(sizeof(paramkey)*10);
484  keylist[0]="C00";
485  keylist[1]="C01";
486  keylist[2]="C10";
487  keylist[3]="C11";
488  keylist[4]="H0";
489  keylist[5]="H1";
490  keylist[6]="A00";
491  keylist[7]="A01";
492  keylist[8]="A10";
493  keylist[9]="A11";
494  return 10;
495  }
496 
497  virtual int getInternalParams(paramval* vallist, int length) {
498  if(length < 10) return 0;
499  vallist[0]=C[0][0];
500  vallist[1]=C[0][1];
501  vallist[2]=C[1][0];
502  vallist[3]=C[1][1];
503  vallist[4]=h[0];
504  vallist[5]=h[1];
505  vallist[6]=A[0][0];
506  vallist[7]=A[0][1];
507  vallist[8]=A[1][0];
508  vallist[9]=A[1][1];
509  return 10;
510  }
511 
512 
513 };
514 
515 AbstractController* getController(int sensornumber, int motornumber,
516  int param1/*=0*/, double param2/*=0*/)
517 {
518  if(param1 < 2) param1 = 2;
520 }
521 
522 
523 
524 #endif
virtual void calculateDelayedValues(double source[BUFFER_SIZE][NUMBER_CHANNELS], paramval number_steps_of_delay_, double *target)
calculate delayed values
Definition: invert3channelcontroller.h:425
std::string paramkey
Definition: configurable.h:85
Abstract class for robot controller (with some basic functionality).
Definition: abstractcontroller.h:46
virtual double squash(double z)
squashing function, to protect against to large weight updates
Definition: invert3channelcontroller.h:113
virtual void learn(const double *x_, const double *x_delay, const double *y_delay)
Definition: invert3channelcontroller.h:358
virtual void step(const sensor *x_, int sensornumber, motor *y_, int motornumber)
performs one step (includes learning). Calulates motor commands from sensor inputs.
Definition: invert3channelcontroller.h:163
Invert3ChannelController()
Definition: invert3channelcontroller.h:121
double xsi4Model[NUMBER_CHANNELS]
Definition: invert3channelcontroller.h:64
virtual double calculateE(const double *x_, const double *x_delay, const double *y_delay)
Definition: invert3channelcontroller.h:271
virtual void stepNoLearning(const sensor *x_, int sensornumber, motor *y_, int motornumber)
performs one step without learning. Calulates motor commands from sensor inputs.
Definition: invert3channelcontroller.h:203
virtual void calculateControllerValues(double *x_smooth, double *y)
calculate controller ouptus
Definition: invert3channelcontroller.h:456
virtual void learnModel(const double *x_actual, double *y_effective)
Definition: invert3channelcontroller.h:396
double sensor
Definition: abstractcontroller.h:48
double paramval
Definition: configurable.h:88
paramval rho
Definition: invertcontroller.h:51
virtual void inverseMatrix(double Q[NUMBER_CHANNELS][NUMBER_CHANNELS], double Q_1[NUMBER_CHANNELS][NUMBER_CHANNELS])
Definition: invert3channelcontroller.h:230
virtual int getInternalParams(paramval *vallist, int length)
Definition: invert3channelcontroller.h:497
paramval eps
Definition: invertcontroller.h:50
double A[NUMBER_CHANNELS][NUMBER_CHANNELS]
model matrix
Definition: invert3channelcontroller.h:56
virtual void calculateSmoothValues(double source[BUFFER_SIZE][NUMBER_CHANNELS], paramval number_steps_for_averaging_, double *target)
Definition: invert3channelcontroller.h:438
AbstractController * getController(int sensornumber, int motornumber, int param1, double param2)
Definition: invert3channelcontroller.h:515
int t
number of steps, needed for ringbuffer x_buffer
Definition: invert3channelcontroller.h:66
paramval delta
Definition: invertcontroller.h:58
double h[NUMBER_CHANNELS]
bias vector
Definition: invert3channelcontroller.h:58
double C[NUMBER_CHANNELS][NUMBER_CHANNELS]
controller matrix
Definition: invert3channelcontroller.h:57
double y_buffer[BUFFER_SIZE][NUMBER_CHANNELS]
buffer for output values, y[tbuffersize]=actual value(if already calculated!), y[(t-1+buffersize)buff...
Definition: invert3channelcontroller.h:61
virtual void putInBuffer(double buffer[BUFFER_SIZE][NUMBER_CHANNELS], const double *values)
Definition: invert3channelcontroller.h:473
virtual int getInternalParamNames(paramkey *&keylist)
Definition: invert3channelcontroller.h:482
class for robot controller that use naglaa's direct matrix inversion for n channels (simple one layer...
Definition: invert3channelcontroller.h:36
double x_buffer[BUFFER_SIZE][NUMBER_CHANNELS]
buffer for input values, x[tbuffersize]=actual value, x[(t-1+buffersize)buffersize]=x(t-1) ...
Definition: invert3channelcontroller.h:60
double xsi4E[NUMBER_CHANNELS]
Definition: invert3channelcontroller.h:63
double motor
Definition: abstractcontroller.h:49
Abstract class (interface) for robot controller that use direct matrix inversion and simple one layer...
Definition: invertcontroller.h:33
virtual double g_s(double z)
Definition: invert3channelcontroller.h:105
paramval factor_a
Definition: invertcontroller.h:55
virtual double g(double z)
neuron transfer function
Definition: invert3channelcontroller.h:97
#define BUFFER_SIZE
Definition: use_java_controller.h:46