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

calibrate_analog.cpp

Go to the documentation of this file.
00001 /************************************************************************************************/
00002 /*! \file calibrate_analog.cpp
00003 *  \brief This file will display to screen the calibration values needed for the analog MotionPak
00004 *  \author $Author: cakinli $
00005 *  \version $Revision: 1.4 $
00006 *  \date    $Date: 2005/04/27 20:00:05 $
00007 ************************************************************************************************/
00008 /*! 
00009 *
00010 ************************************************************************************************/
00011 
00012 /* Running this program, with the appropriate config files, is one way to calibrate the analog MoPak,
00013 including the rategyros and linear accelerometers. Each sensor has a "Offset" (a.k.a. Bias) and
00014 "ScaleFactor" in an associated section of the Whorl config (.cfg) file.  The purpose of this program 
00015 is to give the user these Offsets, which he or she will then manually input into the config file.  
00016 Instructions for the calibration procedure are displayed to the user.*/
00017 
00018 #include <Base/Whorl.h>
00019 #include <Base/WhorlSim.h>
00020 #include <Utils/CfgParse.h>
00021 #include <Utils/Measurement.h>
00022 #include <iostream>
00023 #include <fstream>
00024 #include <string>
00025 using namespace std;
00026 
00027 //
00028 // This is a function to prompt the user at each step in the calibration
00029 //
00030 int promptMenu(int collectRuns)
00031 {
00032         const string direction[6] = {"+Z","-Z","+X","-X","+Y","-Y"};
00033         int userinput = 0;
00034 
00035         if (collectRuns < 6)
00036         {
00037                 cout << "=================================================" << endl;
00038                 cout << " MoPak orientation: " << direction[collectRuns] << " up" << endl;
00039                 cout << " Select number to proceed: 1 = ok,  2= abort program ";
00040                 cin >> userinput;
00041                 if (userinput == 1)
00042                 {
00043                         // collect this data as fast as possible
00044                         cout << " Calibrating, please wait... " << endl;
00045                 } else
00046                 {
00047                         // end program
00048                         cout << endl << " Stopping program... " << endl;
00049                 }
00050         } else
00051         {
00052                 userinput = 1;
00053         }
00054         return userinput;
00055 }               
00056 
00057 int main() 
00058 {
00059         cout << "=================================================" << endl;
00060         cout << " This program will calculate the offset and " << endl;
00061         cout << " scale factor for each of the 3 rate gyros and " << endl;
00062         cout << " linear accelerometers for analog MoPak use. " << endl << endl;
00063         cout << " At this time the MoPak should be placed on a " << endl;
00064         cout << " flat and stationary surface with the extender cable." << endl;
00065         cout << " Follow the prompts to re-orient the MoPak during the procedure. " << endl;
00066 
00067         /** Prepare for parsing */
00068         cfgBody *cfgDat;
00069         CfgParse parser;
00070         
00071         /** Parse out configuration files */
00072         /** note: there is nothing special about this config file other than the **/
00073         /** fact that the Offset values are set to 0.0 and the ScaleFactor is 1.0. **/
00074         cfgDat = parser.go("calibrate_analog.cfg");
00075 
00076         Whorl whorlOne;
00077         whorlOne.Initialize(cfgDat);
00078         double total[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; /* running total to determine avg. */
00079         double avg[6][6]; /* array of averages from all data collections for all sensors */
00080         double xlinavg[4]; /* averages of x-dir neutral linear acceleration */
00081         double ylinavg[4]; /* averages of y-dir neutral linear acceleration */
00082         double zlinavg[4]; /* averages of z-dir neutral linear acceleration */
00083         double linmax[3] = {0.0, 0.0, 0.0}; /* max linear acceleration */
00084         double linmin[3] = {0.0, 0.0, 0.0}; /* min linear acceleration */
00085         double linzero[3] = {0.0, 0.0, 0.0}; /* zero linear acceleration */
00086         double ratezero[3] = {0.0, 0.0, 0.0}; /* zero angular rate */
00087         double scaleFactor[3] = {0.0, 0.0, 0.0};
00088         double offset[3] = {0.0, 0.0, 0.0};
00089         double rateOffset[3] = {0.0, 0.0, 0.0};
00090         
00091         double rad2deg = 180.0/3.1415926535898; /* conversion factor */
00092         int collectRuns = 0; /* number of times user is prompted to collect MoPak data */
00093         int numSamples = 300; /* number of data samples for each calibration run */
00094         int promptResult = 0; /*result of user prompts */
00095         
00096         Measurement xrates[numSamples];
00097         Measurement yrates[numSamples];
00098         Measurement zrates[numSamples];
00099         Measurement xlinacc[numSamples];
00100         Measurement ylinacc[numSamples];
00101         Measurement zlinacc[numSamples];
00102 
00103         promptResult = promptMenu(collectRuns);
00104         while (promptResult == 1 && collectRuns < 6)
00105         {
00106                 for (int i = 0; i<numSamples; i++)
00107                 {
00108                         xrates[i] = whorlOne.GetRateGyro(string("dmu_rg1"))->GetMeasurement();
00109                         yrates[i] = whorlOne.GetRateGyro(string("dmu_rg2"))->GetMeasurement();
00110                         zrates[i] = whorlOne.GetRateGyro(string("dmu_rg3"))->GetMeasurement();
00111                         xlinacc[i] = whorlOne.GetAccelerometer(string("dmu_acc1"))->GetMeasurement();
00112                         ylinacc[i] = whorlOne.GetAccelerometer(string("dmu_acc2"))->GetMeasurement();
00113                         zlinacc[i] = whorlOne.GetAccelerometer(string("dmu_acc3"))->GetMeasurement();
00114                         usleep(1);
00115                 }
00116                 for (int cc = 0; cc<numSamples; cc++)
00117                 {
00118                         total[0] += xrates[cc].GetAsDouble()*-1.0*rad2deg;
00119                         total[1] += yrates[cc].GetAsDouble()*-1.0*rad2deg;
00120                         total[2] += zrates[cc].GetAsDouble()*-1.0*rad2deg;
00121                         total[3] += xlinacc[cc].GetAsDouble()/-9.81;
00122                         total[4] += ylinacc[cc].GetAsDouble()/-9.81;
00123                         total[5] += zlinacc[cc].GetAsDouble()/-9.81;
00124                 }
00125                 for (int  ii = 0; ii < 6; ii++)
00126                 {
00127                         avg[ii][collectRuns] = total[ii]/numSamples;
00128                         // reset total to zero after use
00129                         total[ii] = 0;
00130                 }
00131                 switch (collectRuns)
00132                 {
00133                         case 0:
00134                                 xlinavg[0] = avg[3][collectRuns];
00135                                 ylinavg[0] = avg[4][collectRuns];
00136                                 linmax[2] = avg[5][collectRuns];
00137                                 break;
00138                         case 1:
00139                                 xlinavg[1] = avg[3][collectRuns];
00140                                 ylinavg[1] = avg[4][collectRuns];
00141                                 linmin[2] = avg[5][collectRuns];
00142                                 break;
00143                         case 2:
00144                                 linmax[0] = avg[3][collectRuns];
00145                                 ylinavg[2] = avg[4][collectRuns];
00146                                 zlinavg[0] = avg[5][collectRuns];
00147                                 break;
00148                         case 3:
00149                                 linmin[0] = avg[3][collectRuns];
00150                                 ylinavg[3] = avg[4][collectRuns];
00151                                 zlinavg[1] = avg[5][collectRuns];
00152                                 break;
00153                         case 4:
00154                                 xlinavg[2] = avg[3][collectRuns];
00155                                 linmax[1] = avg[4][collectRuns];
00156                                 zlinavg[2] = avg[5][collectRuns];
00157                                 break;
00158                         case 5:
00159                                 xlinavg[3] = avg[3][collectRuns];
00160                                 linmin[1] = avg[4][collectRuns];        
00161                                 zlinavg[3] = avg[5][collectRuns];
00162                                 break;
00163                         default:
00164                                 break;
00165                 }
00166                 cout << "=================================================" << endl;
00167                 cout << " X-RateGyro avg = " << avg[0][collectRuns] << " V " << endl;
00168                 cout << " Y-RateGyro avg = " << avg[1][collectRuns] << " V " << endl;
00169                 cout << " Z-RateGyro avg = " << avg[2][collectRuns] << " V " << endl;
00170                 cout << " X-LinAcc avg = " << avg[3][collectRuns] << " V " << endl;
00171                 cout << " Y-LinAcc avg = " << avg[4][collectRuns] << " V " << endl;
00172                 cout << " Z-LinAcc avg = " << avg[5][collectRuns] << " V " << endl << endl;
00173 
00174                 /* collect running total of the 6 rate gyro zero values for each gyro */
00175                 ratezero[0] += avg[0][collectRuns];
00176                 ratezero[1] += avg[1][collectRuns];
00177                 ratezero[2] += avg[2][collectRuns];
00178 
00179                 collectRuns++;
00180                 promptResult = promptMenu(collectRuns);
00181         }
00182         
00183         if (promptResult == 1)
00184         {
00185                 /* find average of zero rates */
00186                 for(int b = 0; b<3; b++)
00187                 {
00188                         rateOffset[b] = ratezero[b]/6.0;
00189                 }
00190 
00191                 linzero[0] = (xlinavg[0]+xlinavg[1]+xlinavg[2]+xlinavg[3])/4.0;
00192                 linzero[1] = (ylinavg[0]+ylinavg[1]+ylinavg[2]+ylinavg[3])/4.0;
00193                 linzero[2] = (zlinavg[0]+zlinavg[1]+zlinavg[2]+zlinavg[3])/4.0;
00194         
00195                 cout << "=================================================" << endl;
00196                 cout << " X-LinAcc zero = " << linzero[0] << " V " << endl;
00197                 cout << " Y-LinAcc zero = " << linzero[1] << " V " << endl;
00198                 cout << " Z-LinAcc zero = " << linzero[2] << " V " << endl << endl;
00199         
00200                 cout << " X-LinAcc max, min = " << linmax[0] << ", " << linmin[0] << endl;
00201                 cout << " Y-LinAcc max, min = " << linmax[1] << ", " << linmin[1] << endl;
00202                 cout << " Z-LinAcc max, min = " << linmax[2] << ", " << linmin[2] << endl << endl;
00203         
00204                 for (int i=0; i<3; i++)
00205                 {
00206                         scaleFactor[i] = (-1.0*linmin[i] + 1.0*linmax[i])/2.0;
00207                         offset[i] = (linmin[i]+linzero[i]+linmax[i])/3.0;
00208                 }
00209         
00210                 cout << "=================================================" << endl;
00211                 cout << " X-RateGyro offset = " << rateOffset[0] << endl;
00212                 cout << " Y-RateGyro offset = " << rateOffset[1] << endl;
00213                 cout << " Z-RateGyro offset = " << rateOffset[2] << endl;
00214                 cout << " X-LinAcc scale factor, offset = " << scaleFactor[0] << ", " << offset[0] << endl;
00215                 cout << " Y-LinAcc scale factor, offset = " << scaleFactor[1] << ", " << offset[1] << endl;
00216                 cout << " Z-LinAcc scale factor, offset = " << scaleFactor[2] << ", " << offset[2] << endl;
00217         }
00218         return 0;
00219 }
00220 
00221 // Do not change the comments below - they will be added automatically by CVS
00222 /*****************************************************************************
00223 *       $Log: calibrate_analog.cpp,v $
00224 *       Revision 1.4  2005/04/27 20:00:05  cakinli
00225 *       Retry
00226 *       
00227 *       Revision 1.3  2004/05/27 19:04:49  shoemaker
00228 *       Added linear accelerometer calibration routines
00229 *       
00230 *       Revision 1.2  2004/04/11 19:30:22  shoemaker
00231 *       Increased number of samples taken to improve accuracy
00232 *       
00233 *       Revision 1.1  2004/04/08 06:06:37  shoemaker
00234 *       Added analog MoPak calibration routines
00235 *       
00236 *       Revision 1.5  2004/03/29 16:43:11  shoemaker
00237 *       Added code to work with analog DAQ card code
00238 *       
00239 *       
00240 ******************************************************************************/
00241 

Generated on Wed Sep 5 12:54:18 2007 for DSACSS Operational Code by  doxygen 1.3.9.1