Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

Tools/Math/FourierCoefficient.cpp

Go to the documentation of this file.
00001 /**
00002 * @file FourierCoefficient.cpp
00003 *
00004 * Implementation of class FourierCoefficient.
00005 */
00006 
00007 #include "FourierCoefficient.h"
00008 #include "Tools/Debugging/Debugging.h"
00009 #include "Tools/Streams/InStreams.h"
00010 #include "Tools/Math/Common.h"
00011 
00012 FourierCoefficient::FourierCoefficient():lengthOfPeriod(110)
00013 {
00014   /** init all coefficients to zero */
00015   for(int joint = 0; joint < JointData::numOfJoint; joint++)
00016   {
00017     useLookUp[joint] = false;
00018     for(int c = 0; c < FourierCoefficient::numOfCoeffs; c++)
00019     { 
00020       real[joint][c]        = 0.0; 
00021       imaginary[joint][c]   = 0.0; 
00022       functionLUT[joint][c] = 0.0; 
00023       r[joint][c]           = 0.0; 
00024       phi[joint][c]         = 0.0; 
00025     }
00026   }
00027 }
00028 
00029 
00030 FourierCoefficient::~FourierCoefficient()
00031 { }
00032 
00033 
00034 /* calculate the approximated function value from the fc's
00035 */
00036 long FourierCoefficient::fourierSynth(JointData::JointID joint, unsigned long time, int cMax, double scalingFactor)
00037 {
00038   double functionValue = 0;
00039   long onePeriod = numOfCoeffs * 8;
00040 
00041   time %= onePeriod;
00042 
00043   /* first coefficient is equal to the 
00044   mean value over one period, the first complex
00045   coefficient is always = 0.0, therefore theere is
00046   nothing to be calculated and the loops below 
00047   start with n = 1 rather then n = 0 */
00048   functionValue = real[joint][0]/sqrt((double)numOfCoeffs);
00049 
00050   /*  if the scaling factor is smaller than 0.0, inverse
00051   the direction of the function (play the function backwards) */
00052   long mytime=(long)time;
00053   if (scalingFactor < 0) mytime *= -1;
00054 
00055   //if (useLookUp[joint])
00056   //  return (long )(functionValue + functionLUT[joint][(int)time] * scalingFactor);
00057 
00058   /*  loop through the coefficents 
00059   first do all sines, then all cosines starting 
00060   with the second complex coefficient pair in 
00061   the array */
00062   
00063   double t, b = 2/sqrt((double)numOfCoeffs) * scalingFactor;
00064 
00065   for (int c = 1; c <= cMax; c++)
00066   {
00067     t = mytime*pi2*c/onePeriod;
00068     functionValue += b * (imaginary[joint][c] * sin(t) + real[joint][c] * cos(t));
00069   }
00070   
00071   return (long )functionValue;
00072 }
00073 
00074 long FourierCoefficient::fourierSynth(JointData* jointData, unsigned long time, int cMax)
00075 {
00076   double functionValue = 0;
00077   long onePeriod = numOfCoeffs * 8;
00078 
00079   time %= onePeriod;
00080   double sinTab[200];
00081   double cosTab[200];
00082 
00083   /*  if the scaling factor is smaller than 0.0, inverse
00084   the direction of the function (play the function backwards) */
00085   
00086   double t, b = 2/sqrt((double)numOfCoeffs);
00087 
00088   for (int c = 1; c <= cMax; c++)
00089   {
00090     t = time*pi2*c/onePeriod;
00091     sinTab[c]=b*sin(t);
00092     cosTab[c]=b*cos(t);
00093   }
00094 
00095   for(int j = JointData::legFR1; j <= JointData::legHL3; j++)
00096   {
00097     functionValue = real[j][0]/sqrt((double)numOfCoeffs);
00098     for (int c = 1; c <= cMax; c++)
00099     {
00100       functionValue += imaginary[j][c]*sinTab[c] + real[j][c]*cosTab[c];
00101     }
00102     jointData->data[j] = (long)functionValue;
00103   }
00104   
00105   return (long )functionValue;
00106 }
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 bool FourierCoefficient::calcLUT(JointData::JointID joint, int cMax)
00116 {
00117   useLookUp[joint] = false;
00118 
00119   for (int t = 0; t < lengthOfPeriod; t++)
00120     functionLUT[joint][t] = fourierSynth((JointData::JointID) joint, t, cMax, 1.0) - real[joint][0]/sqrt((double)numOfCoeffs);
00121 
00122   useLookUp[joint] = true;
00123   return true;
00124 }
00125 
00126 bool FourierCoefficient::calcAllLUTs(int cMax)
00127 { 
00128   for (int joint = 0; joint < JointData::numOfJoint; joint++)
00129     calcLUT((JointData::JointID)joint, cMax);
00130   return true;
00131 }
00132 
00133 
00134 
00135 /* function to calculate the coefficients
00136 */
00137 bool FourierCoefficient::calculate(long *functionValues, JointData::JointID joint)
00138 {
00139   double sinPart, cosPart;
00140 
00141   /* Loop through all sines/cosines with freqency c 
00142   * and do correllation
00143   */
00144   for (int c = 0; c < numOfCoeffs; c++)
00145   { 
00146     sinPart = 0.0;
00147     cosPart = 0.0;
00148     for (int i = 0; i < numOfCoeffs; i++)
00149     {
00150       sinPart += functionValues[i] * sin(pi2*i*c/numOfCoeffs);
00151       cosPart += functionValues[i] * cos(pi2*i*c/numOfCoeffs);
00152     }
00153     real[joint][c]      = cosPart/sqrt((double )numOfCoeffs);
00154     imaginary[joint][c] = sinPart/sqrt((double )numOfCoeffs);
00155   }
00156 
00157   return true;
00158 }
00159 
00160 
00161 /* method to shift all phases so that the first sine of the joint "j"
00162 starts with 0 (accordingly, the first cosine amplitude of this joint
00163 is 0).
00164 */
00165 double FourierCoefficient::phaseAlign(JointData::JointID j)
00166 {
00167   calcPhiAndR();
00168   double currentPhaseShift = phi[j][1]; // note that the 1st and not the 0th is used!!
00169 
00170   for (int joint = JointData::legFR1; joint <= JointData::legHL3; joint++)  
00171   {
00172     for(int c = 1; c < FourierCoefficient::numOfCoeffs; c++)
00173     {
00174       phi[joint][c] -= currentPhaseShift * c/numOfCoeffs;
00175 
00176       /*
00177       if (phi[joint][c] > pi2) 
00178         phi[joint][c] -= pi2;
00179       else if (phi[joint][c] < -pi2) 
00180         phi[joint][c] += pi2;
00181 */
00182       //while (phi[joint][c] > pi2) phi[joint][c] -= pi2;
00183     }
00184   }
00185   calcReAndIm();
00186   return currentPhaseShift;
00187 }
00188 
00189 
00190 bool FourierCoefficient::merge(FourierCoefficient *fc0, FourierCoefficient *fc1, double w1, FourierCoefficient *fc2, double w2, FourierCoefficient *fc3, double w3, int numOfC)
00191 {
00192   double phi1, phi2, phi3;
00193 
00194   for (int joint = JointData::legFR1; joint <= JointData::legHL3; joint++)
00195   {
00196     for(int c = 0; c < numOfC; c++)
00197     {
00198       r[joint][c] = fc0->r[joint][c] +
00199                     (fc1->r[joint][c] - fc0->r[joint][c])*w1 +
00200                     (fc2->r[joint][c] - fc0->r[joint][c])*w2 +
00201                     (fc3->r[joint][c] - fc0->r[joint][c])*w3;
00202 
00203       /** always use the (direction of) difference with the smaller abs() */
00204       phi1 = fc1->phi[joint][c] - fc0->phi[joint][c];
00205       if (phi1>pi) phi1-=pi2; else if (phi1<-pi) phi1+=pi2;
00206       phi2 = fc2->phi[joint][c] - fc0->phi[joint][c];
00207       if (phi2>pi) phi2-=pi2; else if (phi2<-pi) phi2+=pi2;
00208       phi3 = fc3->phi[joint][c] - fc0->phi[joint][c];
00209       if (phi3>pi) phi3-=pi2; else if (phi3<-pi) phi3+=pi2;
00210 
00211       phi[joint][c] = fc0->phi[joint][c] + phi1*w1 + phi2*w2 + phi3*w3;
00212     }
00213   }
00214   calcReAndIm(numOfC);
00215   return true;
00216 }
00217 
00218 
00219 
00220 bool FourierCoefficient::merge(FourierCoefficient *fc1, double w1, FourierCoefficient *fc2, double w2, int numOfC)
00221 {
00222   double phi1, phi2;
00223 
00224   for (int joint = JointData::legFR1; joint <= JointData::legHL3; joint++)
00225   {
00226     for(int c = 0; c < numOfC; c++)
00227     {
00228       r[joint][c] = fc1->r[joint][c]*w1 + fc2->r[joint][c]*w2;
00229 
00230       phi1 = fc1->phi[joint][c]; 
00231       phi2 = fc2->phi[joint][c];
00232 
00233       if (phi2 - phi1 > pi) phi2 -= pi2; 
00234       if (phi2 - phi1 < -pi) phi2 += pi2; 
00235 
00236       phi[joint][c] = phi1*w1 + phi2*w2;
00237     }
00238   }
00239   calcReAndIm(numOfC);
00240   return true;
00241 }
00242 
00243 
00244 
00245 bool FourierCoefficient::calcPhiAndR(int numOfC)
00246 {
00247   for (int joint = JointData::legFR1; joint <= JointData::legHL3; joint++)
00248   {
00249     for(int c = 0; c < numOfC; c++)
00250     {
00251       r[joint][c] = sqrt(real[joint][c]*real[joint][c] + imaginary[joint][c]*imaginary[joint][c]);
00252       phi[joint][c] = atan2(imaginary[joint][c],real[joint][c]);
00253     }
00254   }
00255 
00256   return true;
00257 }
00258 
00259 bool FourierCoefficient::calcReAndIm(int numOfC)
00260 {
00261   for (int joint = JointData::legFR1; joint <= JointData::legHL3; joint++)
00262   {
00263     for(int c = 0; c < numOfC; c++)
00264     {
00265       real[joint][c]      = r[joint][c]*cos(phi[joint][c]);
00266       imaginary[joint][c] = r[joint][c]*sin(phi[joint][c]);
00267     }
00268   }
00269 
00270   return true;
00271 }
00272 
00273 
00274 In& operator>>(In& stream,FourierCoefficient& fc)
00275 {
00276   /** @todo read lengthOfPeriod */
00277   for (int joint = JointData::legFR1; joint <= JointData::legHL3; joint++)
00278   {
00279     for(int c = 0; c < FourierCoefficient::numOfCoeffs; c++)
00280     {
00281       stream >> fc.real[joint][c] >> fc.imaginary[joint][c];
00282     }
00283   }
00284   return stream;
00285 }
00286 
00287 Out& operator<<(Out& stream,FourierCoefficient& fc)
00288 {
00289   /** @todo write lengthOfPeriod */
00290   for (int joint = JointData::legFR1; joint <= JointData::legHL3; joint++)
00291   {
00292     for(int c = 0; c < FourierCoefficient::numOfCoeffs; c++)
00293     {
00294       stream << fc.real[joint][c] << fc.imaginary[joint][c];
00295     }
00296     stream << endl;
00297   }
00298   return stream;
00299 }
00300 
00301 
00302 /*
00303  * Change log :
00304  * 
00305  * $Log: FourierCoefficient.cpp,v $
00306  * Revision 1.1.1.1  2004/05/22 17:37:02  cvsadm
00307  * created new repository GT2004_WM
00308  *
00309  * Revision 1.1  2003/10/07 10:13:24  cvsadm
00310  * Created GT2004 (M.J.)
00311  *
00312  * Revision 1.1  2003/09/26 11:40:40  juengel
00313  * - sorted tools
00314  * - clean-up in DataTypes
00315  *
00316  * Revision 1.1.1.1  2003/07/02 09:40:22  cvsadm
00317  * created new repository for the competitions in Padova from the 
00318  * tamara CVS (Tuesday 2:00 pm)
00319  *
00320  * removed unused solutions
00321  *
00322  * Revision 1.18  2003/05/26 12:56:34  dueffert
00323  * bug fixed
00324  *
00325  * Revision 1.17  2003/02/02 23:30:30  jhoffman
00326  * added merge for only two types of motion and more debugging
00327  * and control stuff (mostly needed for performance testing)
00328  *
00329  * Revision 1.16  2003/01/22 22:16:48  jhoffman
00330  * phase align updated and debugged
00331  *
00332  * Revision 1.15  2003/01/21 14:58:39  jhoffman
00333  * increased performance by precalculating sin/cos
00334  *
00335  * Revision 1.14  2003/01/20 18:40:08  dueffert
00336  * optimized: synthesis should do the same but faster
00337  *
00338  * Revision 1.13  2003/01/18 08:26:35  jhoffman
00339  * changes in order to improve performance
00340  *
00341  * Revision 1.12  2003/01/16 09:55:10  jhoffman
00342  * Added "Generic Debug Data" data type. This can be used
00343  * for quick and dirty optimization and debugging, e.g. to send
00344  * parameters to a module through WLAN to adjust it's settings.
00345  * The DebugMessageGenerator is used to for parsing and
00346  * sendig the data
00347  *
00348  * Revision 1.11  2002/12/13 09:54:42  jhoffman
00349  * walking engine now performes walk-like motions, but still not fully functional
00350  *
00351  * Revision 1.10  2002/12/10 16:07:05  dueffert
00352  * Fourier working now
00353  *
00354  * Revision 1.9  2002/12/10 10:47:04  jhoffman
00355  * debugged and pretty much working
00356  *
00357  * Revision 1.8  2002/12/09 15:24:06  dueffert
00358  * some optimisation
00359  *
00360  * Revision 1.7  2002/12/09 14:15:40  jhoffman
00361  * no message
00362  *
00363  * Revision 1.6  2002/12/04 12:21:18  jhoffman
00364  * no message
00365  *
00366  * Revision 1.5  2002/11/22 13:42:08  dueffert
00367  * cleanup
00368  *
00369  * Revision 1.4  2002/11/22 13:41:21  loetzsch
00370  * - removed the FourierCoefficient::loadLegs and ::saveLegs functions
00371  *   (streaming operators are now used)
00372  * - .fcb files have text format now
00373  * . moved the .fcb files from /Config to /Config/Fourier
00374  *
00375  * Revision 1.3  2002/11/19 17:14:14  risler
00376  * coding conventions: renamed JointData::joint to JointID, GetName to getName
00377  *
00378  * Revision 1.2  2002/09/22 18:40:54  risler
00379  * added new math functions, removed GTMath library
00380  *
00381  * Revision 1.1  2002/09/10 15:26:40  cvsadm
00382  * Created new project GT2003 (M.L.)
00383  * - Cleaned up the /Src/DataTypes directory
00384  * - Removed Challenge Code
00385  * - Removed processing of incoming audio data
00386  * - Renamed AcousticMessage to SoundRequest
00387  *
00388  * Revision 1.2  2002/07/23 13:32:57  loetzsch
00389  * new streaming classes
00390  *
00391  * removed many #include statements
00392  *
00393  * Revision 1.1.1.1  2002/05/10 12:40:13  cvsadm
00394  * Moved GT2002 Project from ute to tamara.
00395  *
00396  * Revision 1.10  2002/05/02 12:12:33  kallnik
00397  * GTMath
00398  *
00399  * Revision 1.9  2002/04/25 14:50:37  kallnik
00400  * changed double/float to double
00401  * added several #include GTMath
00402  *
00403  * PLEASE use double
00404  *
00405  * Revision 1.8  2002/04/23 15:00:06  jhoffman
00406  * changes and additions
00407  *
00408  * Revision 1.7  2002/04/03 16:44:31  jhoffman
00409  * added "stabilizeRobot" to motionControl (which is turned off as a default)
00410  *
00411  * Revision 1.4  2002/03/19 13:23:50  jhoffman
00412  * no message
00413  *
00414  * Revision 1.3  2002/03/19 12:11:14  jhoffman
00415  * extended functionality (synth, load, save, ...)
00416  *
00417  * Revision 1.2  2002/03/12 14:10:48  jhoffman
00418  * added fourier synthesis functionality which calculates the FT from the coefficients
00419  *
00420  * Revision 1.1  2002/01/26 20:22:52  juengel
00421  * no message
00422  *
00423  *
00424  */
00425 

Generated on Thu Sep 23 19:57:38 2004 for GT2004 by doxygen 1.3.6