Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

test/freqresp.cpp

Go to the documentation of this file.
00001 
00002 // This program will run a sine wave with a given amplitude, frequency, and DC
00003 // offset to the motor inputs. It will record the wheel speeds to 
00004 // /tmp/freq_resp.dat 
00006 
00007 
00008 #include "../truckd/hw_interface.h"
00009 #include <math.h>
00010 #include <unistd.h>
00011 #include <fstream>
00012 #include <iostream>
00013 #include <signal.h>
00014 #include <sys/time.h>
00015 #include <errno.h>
00016 
00017 using namespace std;
00018 
00019 int quit=0;
00020 
00021 
00022 // signal handler will set quit the first time ctrl-c is pressed 
00023 // called and will force on exit the second time
00024 void sighandler(int signum) {
00025   if (signum == SIGINT) {
00026     if (!quit) {      
00027       cerr << "caught ctrl-C quitting" << endl;
00028       quit = 1;
00029     } else {
00030       cerr << "second ctrl-C forcing exit" << endl;
00031       exit (EXIT_FAILURE);
00032     }
00033   } else {
00034     cerr << "caught unknown signal?" << endl;
00035   }
00036 }
00037 
00038 //does error checking on do get time of day
00039 int getTime(struct timeval &time) {
00040   if (gettimeofday(&time,NULL) == -1) {
00041     cerr << "error with gettimeofday : " << strerror(errno) << endl;
00042     return -1;
00043   }
00044   return 0;
00045 }
00046 
00047 //returns the difference between two timevalues in milliseconds
00048 int timeDiffMS(struct timeval now, struct timeval old) {
00049   return (now.tv_sec - old.tv_sec) * 1000 + (now.tv_usec - old.tv_usec) / 1000;  
00050 }       
00051 
00052 
00053 int main(int argc, char *argv[]) {
00054 
00055 
00056   if ((argc != 5) && (argc != 6)) {
00057     cout <<
00058       "desc  : produces a sine wave input to the motor controller,\n" 
00059       "        measures motor response, and saves data to a file\n" 
00060       "usage : freqresp <options> freq P2Pamp DCoff\n" 
00061       "    freq    = frequecy of input sine wave (should be < 1HZ)\n" 
00062       "    P2Pamp  = peak to peak amplitude of input sine wave\n" 
00063       "    DCoff   = average value (DC offset) of sine wave output\n" 
00064       "    options = -f <file> ; -t <time>\n" 
00065       "       file = file to save data too (default = /tmp/freqresp.dat\n"
00066       "       time = number of seconds to run test for (default = 100 seconds)\n";
00067       return -1;
00068   }  
00069 
00070   char *filename = "/tmp/freqresp.dat";
00071   float runTime = 100;
00072 
00073   // parse any command line options
00074   while(1) {
00075     opterr = 0;
00076     int opt = getopt(argc,argv,":t:f:");
00077 
00078     if (opt == -1) 
00079       break;
00080     
00081     switch (opt) {
00082     case 'f':
00083       filename = optarg;
00084       break;
00085     case 't':
00086       if (sscanf(optarg,"%f", &runTime) != 1) {
00087         cerr << "can't convert '" << optarg << "' to number" << endl;
00088         return -1;
00089       }
00090       break;
00091     case '?':
00092       cerr << "unknown option '" << (char) optopt << "'" << endl;
00093       return -1;
00094     case ':':
00095       cerr << "missing argument for -" << (char) optopt << endl;
00096       return -1;
00097     default:
00098       cerr << "weight getopt result?" << endl;
00099       return -1;
00100     }
00101   } 
00102         
00103   ofstream data(filename);
00104   if (!data) {
00105     cerr << "error openning file '" << filename << "'" << endl;
00106     return -1;
00107   }
00108             
00109   float freq, p2p, dc_off;
00110 
00111   //parse command-line arguments
00112   if (sscanf(argv[optind], "%f",&freq) != 1) {
00113     cerr << "error : '" << argv[optind] << "' is not a number" << endl;
00114     return -1;
00115   }
00116   if (sscanf(argv[optind+1], "%f",&p2p) != 1) {
00117     cerr << "error : '" << argv[optind+1] << "' is not a number" << endl;
00118     return -1;
00119   }
00120   if (sscanf(argv[optind+2], "%f",&dc_off) != 1) {
00121     cerr << "error : '" << argv[optind+2] << "' is not a number" << endl;
00122     return -1;
00123   }
00124 
00125   cout << "running for " << runTime << " seconds" << endl;
00126   cout << "saving results to '" << filename << "'" << endl;  
00127   cout << " running with fq=" << freq << " p2p=" << p2p << " off=" << dc_off << endl;
00128   data << "# running with fq=" << freq << " p2p=" << p2p << " off=" << dc_off << endl;  
00129 
00130   //initialize intreface to truck hardware
00131   hwInterface hw( 1 /*enable write control*/);
00132   hw.reset();  
00133 
00134   // install ctrl-c signal handler
00135   if (signal(SIGINT,sighandler) == SIG_ERR) {
00136     cerr << "error installing signal handler" << endl;
00137     return -1;
00138   }
00139 
00140   // initialize variables for control loop
00141   float avgTickDelta = 0.0f;
00142   float avgTickDelta2 = 0.0f;
00143   float time = 0.0f;
00144   int cycleCount = 0;
00145   struct timeval startTime, currentTime;
00146   hw.readStatus();
00147   float oldTicks = (float) (hw.encTicks(0) + hw.encTicks(1) + hw.encTicks(2) + hw.encTicks(3));
00148   if (getTime(startTime))
00149     return -1;
00150 
00151   //run loop until time runs out or ctrl-c is pushed
00152   while ((!quit) && (time <= runTime)) {    
00153     hw.readStatus();
00154     
00155     // update stats 
00156     float ticks = (float) (hw.encTicks(0) + hw.encTicks(1) + hw.encTicks(2) + hw.encTicks(3));
00157     float tickDelta = ticks-oldTicks;
00158     oldTicks = ticks;
00159     avgTickDelta += tickDelta;  
00160     avgTickDelta2 += tickDelta * tickDelta;
00161     ++cycleCount;
00162 
00163     // set output power
00164     float power = dc_off + 0.5f * p2p * sinf(2.0f * M_PI * time * freq);
00165     hw.setSCPower(power);
00166     hw.writeControl();
00167 
00168     // write stats to data file
00169     if (getTime(currentTime)) 
00170       break;            
00171     data << timeDiffMS(currentTime,startTime) << '\t' 
00172          << time << '\t' 
00173          << power << '\t' 
00174          << tickDelta << endl;
00175     time += 0.100;  //use 100ms timing loop    
00176 
00177     // wait 100ms
00178     for (int i=0; i<10; ++i)
00179       hw.wait();
00180   }
00181 
00182   // make sums into averages
00183   if (cycleCount > 0) {
00184     avgTickDelta /= (float) cycleCount;
00185     avgTickDelta2 /= (float) cycleCount;
00186   }
00187 
00188   data << "# Ran for " << time << " seconds : " 
00189        << "tick delta : average=" << avgTickDelta
00190        << " stdev=" << sqrtf(avgTickDelta2 - avgTickDelta*avgTickDelta) << endl;
00191 
00192   cout << " E(X^2) = " << avgTickDelta2 << endl;
00193   cout << "Ran for " << time << " seconds : "   
00194        << "tick delta : average=" << avgTickDelta
00195        << " stdev=" << sqrtf(avgTickDelta2 - avgTickDelta*avgTickDelta) << endl;
00196 
00197   // set power back to 0
00198   hw.setSCPower(0);
00199 
00200   return 0;
00201 }
00202 
00203 
00204 
00206 // LOST CODE : maybe it will be used someday
00208 
00209 /*
00210 class freqTest
00211 {
00212  protected:
00213   hwInterface *hw;
00214   float freq, p2p, dc_off;
00215   timeval startTime;
00216   float currentTime;
00217   float oldSpeed;
00218   float tickDelta;
00219   float avgTickDelta;
00220   float phase;
00221 
00222  public:  
00223   freqTest(hwInterface &hw, float freq, float p2p, float dc_off) : 
00224     hw(&hw),
00225     freq(freq),
00226     p2p(p2p),
00227     dc_off(dc_off)    
00228     currentTime(0.0f),
00229     oldSpeed(0.0f),
00230     tickDelta(0),
00231     avgTickDelta(0),    
00232   {
00233     if(getTime(startTime))
00234       exit(EXIT_FAILURE);    
00235   }
00236     
00237   void step(void) {
00238     hw->readStatus();
00239     
00240     //determine what next speed controller power setting will be
00241     float power = dc_off + 0.5f * p2p * sinf(2f * M_PI * (time * freq) - phase);
00242     hw->setSCPower(power);
00243     
00244     //update stats
00245     int ticks = hw.encTicks(0) + hw.encTicks(1) + hw.encTicks(2) + hw.encTicks(3);
00246     tickDelta = ticks-oldTicks;
00247     oldTicks = ticks;
00248 
00249     cycleCount
00250 
00251     hw->writeControl();
00252   };
00253 */

Generated on Fri Sep 1 14:25:54 2006 for Raptor by  doxygen 1.4.4