/***************************************************************************** * * * FOX Controller Library, Version 1.3.3. * * * * Copyright (C) 1998,1999,2000 Russell Smith (rl.smith@auckland.ac.nz) * * * * The FOX Controller Library is free software; you can redistribute it * * and/or modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either version * * 2 of the License, or (at your option) any later version. * * * * The FOX Controller Library is distributed in the hope that it will be * * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with the Fox Controller Library; see the file COPYING.LIB. * * If not, write to the Free Software Foundation, Inc., 59 Temple Place - * * Suite 330, Boston, MA 02111-1307, USA. * * * *****************************************************************************/ /* Test of the FOX-N algorithm on linear gantry crane system. The crane model is two masses (m1 and m2) on a line with a spring connecting them. m1 is the cart and m2 is the pendulum. The state variables are x1,x2,dx1,dx2. The equations of motion are: ddx1 = (x2-x1+f)/m1 (ddx1 = d^2(x1)/dt^2) ddx2 = (x1-x2)/m2 The system includes an "internal" PD controller which adds an internal force fint to f : f = fext + fint fint = a*x1 + b*x2 + c*dx1 + d*dx2 The cart is subject to coloumb friction. */ #include #include #include #include #include "fox-n.h" cftype frandom() { return cftype(random())/cftype(RAND_MAX); } cftype softsign (cftype x) { x *= 100.0; if (x > 1.0) return 1.0; else if (x < -1.0) return -1.0; else return x; } void PlotData (int n, float *y) { for (int i=0; i 100) - 3.0; PlotData (T,xref); // setup fox const int num_inputs = 4; const int num_weights = 100000; const int history = 100; //150; const int C = 10; const int ny = 2; //3; FoxN fox (num_inputs,cmac_input_info,num_weights,C,ny, Adata,Bdata,Cdata,history); fox.SetEligibilityMode (1); // setup storage cftype *this_x1 = new cftype [T]; cftype *this_x2 = new cftype [T]; cftype *this_dx2 = new cftype [T]; cftype *this_des_dx2 = new cftype [T]; cftype *this_f = new cftype [T]; cftype *save_x1 = new cftype [T]; cftype *save_x2 = new cftype [T]; cftype *save_dx2 = new cftype [T]; cftype *save_des_dx2 = new cftype [T]; cftype *save_f = new cftype [T]; for (int i=0; i? x1; max[1] = max[1] >? x2; max[2] = max[2] >? dx1; max[3] = max[3] >? dx2; // get desired dx2 cftype desired_dx2 = 1.5 * atan (1.0*(xref[i] - x2)); // cftype input = cftype(i)*kh + kh/2.0; cftype input[4]; input[0] = x1 - xref[i]; input[1] = dx1; input[2] = x2 - xref[i]; input[3] = dx2; fox.Map (input); cftype fint = cka*x1 + ckb*x2 + ckc*dx1 + ckd*dx2; cftype f = fint + fox.Output(); // if (i > 250) f = 0; // to check cart friction this_x1[i] = x1; this_x2[i] = x2; this_dx2[i] = dx2; this_des_dx2[i] = desired_dx2; this_f[i] = f; cftype error = (desired_dx2 - dx2); // if (fabs(error) > 5.0) error = 0.0; // Important! cftype learning_rate = 0.1; // fox.LimitOutput (learning_rate * 0.005); // fox.LimitOutputDerivative (learning_rate * 0.01); // fox.Train (error * learning_rate); // penalize overshoots static cftype old_error = 0; if (fabs(error) > fabs(old_error)) fox.Train (error * learning_rate); else fox.Train (error * learning_rate * 0.1); old_error = error; cftype ddx1,ddx2; cftype cff; // cart coloumb friction force cff = -1.0 * softsign (dx1); ddx1 = (x2 - x1 + f + cff) / m1; // divide by mass m1 ddx2 = (x1 - x2) / m2; // divide by mass m2 dx1 += kh * ddx1; dx2 += kh * ddx2; x1 += kh * dx1; x2 += kh * dx2; } // plot the results if ((iteration % 1)==0) { fprintf (stderr,"%d\n",iteration); fprintf (stderr,"min = %f %f %f %f\n",min[0],min[1],min[2],min[3]); fprintf (stderr,"max = %f %f %f %f\n",max[0],max[1],max[2],max[3]); #define DOPLOT(var) \ PlotData (T,this_ ## var); \ tmp = this_ ## var; \ this_ ## var = save_ ## var; \ save_ ## var = tmp; cftype *tmp; DOPLOT (x1); DOPLOT (x2); DOPLOT (dx2); DOPLOT (des_dx2); DOPLOT (f); } } return 0; }