SonarHysteresisTest.C

00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <math.h>
00004 #include <vector>
00005 #include <fftw3.h>
00006 
00007 //#include "cheetah.h"
00008 //#include "RealData_nopinger.H"
00009 #include "RealData_pinger.H"
00010 //#include "DummyData256.H"
00011 #include "FFTBinPrediction.H"
00012 
00013 double sign(double val) {
00014   if (val < 0)
00015     return -1.0;
00016   else if (val > 0)
00017     return 1.0;
00018   return 0.0;
00019 }
00020 
00021 // Globals
00022 const double SPEED_SOUND_WATER  = 1482;  // [m/s]
00023 const double SENSOR_SPACING_2_1 = 0.024; // [m]
00024 const double SENSOR_SPACING_3_2 = 0.024; // [m]
00025 const double SENSOR_SPACING_1_3 = 0.024; // [m]
00026 const int DATA_RETENTION_LENGTH = 1024;
00027 
00028 // Declare Cheetah Variables
00029 //Cheetah    handle;
00030 int        port, bitrate;
00031 //uint8_t    mode = 0;
00032 //int        ret, input, ready_bit, valid_data_point;
00033 
00034 // FFT & Bin Prediction
00035 const int  FP_FFT_LENGTH = 32;  // First-pass FFT length
00036 double     BIN_PREDICTION_M = 10.59;
00037 double     BIN_PREDICTION_B = -1193.82;
00038 int        target_frequency1, target_frequency2;
00039 double     target_wavelength1, target_wavelength2;
00040 double     angle_estimate1, angle_estimate2;
00041 double     bin_current_mag_sq_1;
00042 double     bin_current_mag_sq_2;
00043 double     bin_current_mag_sq_3;
00044 double     adc1_bin_mean, adc2_bin_mean, adc3_bin_mean;
00045 std::vector<bool> FP_bin_indicator;
00046 
00047 // Raw Data
00048 //const int  TX_LENGTH = FP_FFT_LENGTH * 3 * 2;
00049 const int  TX_LENGTH = 512 * 3 * 2;
00050 uint8_t    data_in[TX_LENGTH];
00051 uint8_t    data_out[2];
00052 
00053 // Hysterisis Vars
00054 const int FP_BIN_HISTORY_LENGTH = 10;//10;
00055 const double MEAN_SCALE_FACTOR = 8.0;
00056 const int FP_MIN_SAMPLE_LENGTH = 128;
00057 int FP_bin_mean_idx = 1;
00058 double FP_adc1_bin_history[FP_BIN_HISTORY_LENGTH];
00059 double FP_adc2_bin_history[FP_BIN_HISTORY_LENGTH];
00060 double FP_adc3_bin_history[FP_BIN_HISTORY_LENGTH];
00061 int    FP_bin_history_fill = 0;
00062 std::vector<double> *adc1_data_history, *adc2_data_history, *adc3_data_history, *tmp_data_buffer;
00063 
00064 
00065 int main (int argc, char const *argv[]) {
00066   port = 0;
00067   bitrate = 10000;
00068 
00069   // Assign Target Frequencies
00070   target_frequency1  = 30000; //atoi(argv[2]);
00071   target_frequency2  = 27000; //atoi(argv[3]);
00072   target_wavelength1 = (double)SPEED_SOUND_WATER / (double)target_frequency1;
00073   target_wavelength2 = (double)SPEED_SOUND_WATER / (double)target_frequency2;
00074 
00075   // Calculate Sampling Frequency and Target Bin
00076   // For affine bin prediction, use m = 10.59, b = -1193.82 and a
00077   // window-HALFWIDTH of 5.
00078   FFTBinAffinePrediction FP_f1_bin(bitrate,
00079                                        FP_FFT_LENGTH,
00080                                        target_frequency1,
00081                                        BIN_PREDICTION_M,
00082                                        BIN_PREDICTION_B,
00083                                        3);
00084   FFTBinAffinePrediction FP_f2_bin(bitrate,
00085                                        FP_FFT_LENGTH,
00086                                        target_frequency2,
00087                                        BIN_PREDICTION_M,
00088                                        BIN_PREDICTION_B,
00089                                        3);
00090   printf("Sonar: First-pass Target Bin 1: %d\n", FP_f1_bin.getTargetBin());
00091   printf("Sonar: First-pass Target Bin 2: %d\n", FP_f2_bin.getTargetBin());
00092 
00093   // Declare Data Vectors
00094   //double *FP_adc1_samples, *FP_adc2_samples, *FP_adc3_samples;
00095   double FP_adc1_samples[FP_FFT_LENGTH], FP_adc2_samples[FP_FFT_LENGTH], FP_adc3_samples[FP_FFT_LENGTH];
00096   fftw_complex *FP_fft1, *FP_fft2, *FP_fft3;
00097   fftw_complex *SP_fft1, *SP_fft2, *SP_fft3;
00098   fftw_plan FP_fft_plan1, FP_fft_plan2, FP_fft_plan3;
00099   fftw_plan SP_fft_plan1, SP_fft_plan2, SP_fft_plan3;
00100 
00101   // Allocate Memory for Data Vectors
00102   FP_fft1 = (double (*)[2]) fftw_malloc ( sizeof ( fftw_complex ) * (( FP_FFT_LENGTH / 2 ) + 1) );
00103   FP_fft2 = (double (*)[2]) fftw_malloc ( sizeof ( fftw_complex ) * (( FP_FFT_LENGTH / 2 ) + 1) );
00104   FP_fft3 = (double (*)[2]) fftw_malloc ( sizeof ( fftw_complex ) * (( FP_FFT_LENGTH / 2 ) + 1) );
00105 
00106   adc1_data_history = new std::vector<double>;
00107   adc2_data_history = new std::vector<double>;
00108   adc3_data_history = new std::vector<double>;
00109 
00110   FP_fft_plan1 = fftw_plan_dft_r2c_1d(FP_FFT_LENGTH, FP_adc1_samples, FP_fft1, FFTW_ESTIMATE);
00111   FP_fft_plan2 = fftw_plan_dft_r2c_1d(FP_FFT_LENGTH, FP_adc2_samples, FP_fft2, FFTW_ESTIMATE);
00112   FP_fft_plan3 = fftw_plan_dft_r2c_1d(FP_FFT_LENGTH, FP_adc3_samples, FP_fft3, FFTW_ESTIMATE);
00113 
00114   int z = 0;
00115   while (z++ < 700) {
00116     // Append current data to history vectors
00117     adc1_data_history->insert(adc1_data_history->end(), data1 + z * 256, data1 + (z + 1) * 256);
00118     adc2_data_history->insert(adc2_data_history->end(), data2 + z * 256, data2 + (z + 1) * 256);
00119     adc3_data_history->insert(adc3_data_history->end(), data3 + z * 256, data3 + (z + 1) * 256);
00120 
00121     // Check data history vector length constraints
00122     if (adc1_data_history->size() > DATA_RETENTION_LENGTH) {
00123       //printf("Data history is too long, reducing vector sizes\n");
00124       tmp_data_buffer = new std::vector<double> (adc1_data_history->begin() + adc1_data_history->size() - DATA_RETENTION_LENGTH, adc1_data_history->end());
00125       delete adc1_data_history;
00126       adc1_data_history = tmp_data_buffer;
00127       tmp_data_buffer = NULL;
00128     }
00129     if (adc2_data_history->size() > DATA_RETENTION_LENGTH) {
00130       tmp_data_buffer = new std::vector<double> (adc2_data_history->begin() + adc2_data_history->size() - DATA_RETENTION_LENGTH, adc2_data_history->end());
00131       delete adc2_data_history;
00132       adc2_data_history = tmp_data_buffer;
00133       tmp_data_buffer = NULL;
00134     }
00135     if (adc3_data_history->size() > DATA_RETENTION_LENGTH) {
00136       tmp_data_buffer = new std::vector<double> (adc3_data_history->begin() + adc3_data_history->size() - DATA_RETENTION_LENGTH, adc3_data_history->end());
00137       delete adc3_data_history;
00138       adc3_data_history = tmp_data_buffer;
00139       tmp_data_buffer = NULL;
00140     }
00141 
00142     for (int vector_idx = 0; vector_idx <= adc1_data_history->size() - FP_FFT_LENGTH; vector_idx += FP_FFT_LENGTH) {
00143       //fprintf(stderr, "Copying vector memory\n");
00144       std::copy(adc1_data_history->begin() + vector_idx, adc1_data_history->begin() + vector_idx + FP_FFT_LENGTH, FP_adc1_samples);
00145       std::copy(adc2_data_history->begin() + vector_idx, adc2_data_history->begin() + vector_idx + FP_FFT_LENGTH, FP_adc2_samples);
00146       std::copy(adc3_data_history->begin() + vector_idx, adc3_data_history->begin() + vector_idx + FP_FFT_LENGTH, FP_adc3_samples);
00147       //fprintf(stderr, "Done copying vector memory\n");
00148       //FP_adc1_samples = data1 + z * FP_FFT_LENGTH;
00149       //FP_adc2_samples = data2 + z * FP_FFT_LENGTH;
00150       //FP_adc3_samples = data3 + z * FP_FFT_LENGTH;
00151       
00152       /*for (int m = 0; m < FP_FFT_LENGTH; ++m)
00153         printf("%5.0f ", FP_adc1_samples[m]);
00154       printf("\n");*/
00155   
00156       FP_fft_plan1 = fftw_plan_dft_r2c_1d(FP_FFT_LENGTH, FP_adc1_samples, FP_fft1, FFTW_ESTIMATE);
00157       FP_fft_plan2 = fftw_plan_dft_r2c_1d(FP_FFT_LENGTH, FP_adc2_samples, FP_fft2, FFTW_ESTIMATE);
00158       FP_fft_plan3 = fftw_plan_dft_r2c_1d(FP_FFT_LENGTH, FP_adc3_samples, FP_fft3, FFTW_ESTIMATE);
00159       //FP_fft_plan1 = fftw_plan_dft_r2c_1d(FP_FFT_LENGTH, (double *)&adc1_data_history[vector_idx], FP_fft1, FFTW_ESTIMATE);
00160       //FP_fft_plan2 = fftw_plan_dft_r2c_1d(FP_FFT_LENGTH, (double *)&adc2_data_history[vector_idx], FP_fft2, FFTW_ESTIMATE);
00161       //FP_fft_plan3 = fftw_plan_dft_r2c_1d(FP_FFT_LENGTH, (double *)&adc3_data_history[vector_idx], FP_fft3, FFTW_ESTIMATE);
00162       
00163       // Perform FFT on current input data
00164       //fprintf(stderr, "Pre-FFT Notice\n");
00165       fftw_execute(FP_fft_plan1);
00166       fftw_execute(FP_fft_plan2);
00167       fftw_execute(FP_fft_plan3);
00168       //fprintf(stderr, "FFT Complete\n");
00169   
00170       // Calculate Gaussian weighted sums surrounding predicted bin
00171       int FP_target_bin = FP_f1_bin.getTargetBin();
00172   
00173       // Populate current bin magnitude array
00174       bin_current_mag_sq_1 = FP_fft1[FP_target_bin][0] * FP_fft1[FP_target_bin][0] + FP_fft1[FP_target_bin][1] * FP_fft1[FP_target_bin][1];
00175       bin_current_mag_sq_2 = FP_fft2[FP_target_bin][0] * FP_fft2[FP_target_bin][0] + FP_fft2[FP_target_bin][1] * FP_fft2[FP_target_bin][1];
00176       bin_current_mag_sq_3 = FP_fft3[FP_target_bin][0] * FP_fft3[FP_target_bin][0] + FP_fft3[FP_target_bin][1] * FP_fft3[FP_target_bin][1];
00177       //fprintf(stderr, "Bin Magnitudes Selected\n");
00178   
00179       // Index Check
00180       if (FP_bin_mean_idx >= FP_BIN_HISTORY_LENGTH)
00181         FP_bin_mean_idx = 0;
00182   
00183       // Initilize Mean Array
00184       if (FP_bin_history_fill < FP_BIN_HISTORY_LENGTH) {
00185         FP_adc1_bin_history[FP_bin_mean_idx] = bin_current_mag_sq_1;
00186         FP_adc2_bin_history[FP_bin_mean_idx] = bin_current_mag_sq_2;
00187         FP_adc3_bin_history[FP_bin_mean_idx] = bin_current_mag_sq_3;
00188         ++FP_bin_mean_idx;
00189         
00190         fftw_destroy_plan(FP_fft_plan1);
00191         fftw_destroy_plan(FP_fft_plan2);
00192         fftw_destroy_plan(FP_fft_plan3);
00193         ++FP_bin_history_fill;
00194         continue;
00195       }
00196       
00197       adc1_bin_mean = 0;
00198       adc2_bin_mean = 0;
00199       adc3_bin_mean = 0;
00200       
00201       for (int i = 0; i < FP_BIN_HISTORY_LENGTH; ++i) {
00202         adc1_bin_mean += FP_adc1_bin_history[i];
00203         adc2_bin_mean += FP_adc2_bin_history[i];
00204         adc3_bin_mean += FP_adc3_bin_history[i];
00205       }
00206       adc1_bin_mean /= (double)FP_BIN_HISTORY_LENGTH;
00207       adc2_bin_mean /= (double)FP_BIN_HISTORY_LENGTH;
00208       adc3_bin_mean /= (double)FP_BIN_HISTORY_LENGTH;
00209   
00210       if (bin_current_mag_sq_1 > MEAN_SCALE_FACTOR * adc1_bin_mean &&
00211           bin_current_mag_sq_2 > MEAN_SCALE_FACTOR * adc2_bin_mean &&
00212           bin_current_mag_sq_3 > MEAN_SCALE_FACTOR * adc3_bin_mean) {
00213         FP_bin_indicator.push_back(true);
00214         printf("1 ");
00215         printf("%15.0f\n", bin_current_mag_sq_3);
00216       } else {
00217         FP_bin_indicator.push_back(false);
00218         //printf("0 ");
00219         //printf("%15.0f\n", bin_current_mag_sq_3);
00220         FP_adc1_bin_history[FP_bin_mean_idx] = bin_current_mag_sq_1;
00221         FP_adc2_bin_history[FP_bin_mean_idx] = bin_current_mag_sq_2;
00222         FP_adc3_bin_history[FP_bin_mean_idx] = bin_current_mag_sq_3;
00223         //printf("%10.0f, %10.0f, %10.0f\n", adc1_bin_mean, adc2_bin_mean, adc3_bin_mean);
00224         ++FP_bin_mean_idx;
00225       }
00226   
00227       
00228   
00229       if (FP_bin_indicator[0] == 0 && FP_bin_indicator[1] == 1) {
00230         printf("Just had a pulse!\n");
00231         
00232         int SP_bin_count = 0;
00233         while (FP_bin_indicator[SP_bin_count + 1] != 0)
00234           ++SP_bin_count;
00235         printf("Signal Bin Count of %d\n", SP_bin_count);
00236         
00237         if (SP_bin_count * FP_FFT_LENGTH >= FP_MIN_SAMPLE_LENGTH) {
00238           int SP_fft_length = SP_bin_count * FP_FFT_LENGTH;
00239           
00240           // Copy the sample data into new double array
00241           double *SP_adc1_samples = new double[SP_fft_length];
00242           double *SP_adc2_samples = new double[SP_fft_length];
00243           double *SP_adc3_samples = new double[SP_fft_length];
00244           //std::copy(adc1_data_history->end() - (SP_bin_count + 1) * FP_FFT_LENGTH, adc1_data_history->end() - FP_FFT_LENGTH, SP_adc1_samples);
00245           std::copy(adc1_data_history->begin() + vector_idx - (SP_bin_count) * FP_FFT_LENGTH, adc1_data_history->begin() + vector_idx, SP_adc1_samples);
00246           std::copy(adc2_data_history->begin() + vector_idx - (SP_bin_count) * FP_FFT_LENGTH, adc2_data_history->begin() + vector_idx, SP_adc2_samples);
00247           std::copy(adc3_data_history->begin() + vector_idx - (SP_bin_count) * FP_FFT_LENGTH, adc3_data_history->begin() + vector_idx, SP_adc3_samples);
00248           
00249           // Allocate Memory for Data Arrays
00250           SP_fft1 = (double (*)[2]) fftw_malloc ( sizeof ( fftw_complex ) * (( (SP_fft_length) / 2 ) + 1) );
00251           SP_fft2 = (double (*)[2]) fftw_malloc ( sizeof ( fftw_complex ) * (( (SP_fft_length) / 2 ) + 1) );
00252           SP_fft3 = (double (*)[2]) fftw_malloc ( sizeof ( fftw_complex ) * (( (SP_fft_length) / 2 ) + 1) );
00253           
00254           SP_fft_plan1 = fftw_plan_dft_r2c_1d(FP_FFT_LENGTH, SP_adc1_samples, SP_fft1, FFTW_ESTIMATE);
00255           SP_fft_plan2 = fftw_plan_dft_r2c_1d(FP_FFT_LENGTH, SP_adc1_samples, SP_fft2, FFTW_ESTIMATE);
00256           SP_fft_plan3 = fftw_plan_dft_r2c_1d(FP_FFT_LENGTH, SP_adc1_samples, SP_fft3, FFTW_ESTIMATE);
00257           
00258           // Perform FFT on current input data
00259           fftw_execute(SP_fft_plan1);
00260           fftw_execute(SP_fft_plan2);
00261           fftw_execute(SP_fft_plan3);
00262           
00263           FFTBinAffinePrediction SP_f1_bin(bitrate,
00264                                            SP_fft_length,
00265                                            target_frequency1,
00266                                            BIN_PREDICTION_M,
00267                                            BIN_PREDICTION_B,
00268                                            3);
00269           /*FFTBinAffinePrediction SP_f2_bin(bitrate,
00270                                            SP_fft_length,
00271                                            target_frequency2,
00272                                            BIN_PREDICTION_M,
00273                                            BIN_PREDICTION_B,
00274                                            3);*/
00275           
00276           int SP_target_bin = SP_f1_bin.getTargetBin();
00277           
00278           fprintf(stderr, "SP Target Bin: %d\n", SP_target_bin);
00279           
00280           // Calculate Phase of each signal found on each ADC
00281           double phase1 = atan2((double)SP_fft1[(int)SP_target_bin][1], (double)SP_fft1[(int)SP_target_bin][0]);
00282           double phase2 = atan2((double)SP_fft2[(int)SP_target_bin][1], (double)SP_fft2[(int)SP_target_bin][0]);
00283           double phase3 = atan2((double)SP_fft3[(int)SP_target_bin][1], (double)SP_fft3[(int)SP_target_bin][0]);
00284           
00285           // Calculate usable phase differences
00286           double delta1 = phase2 - phase1;
00287           double delta2 = phase3 - phase2;
00288           double delta3 = phase1 - phase3;
00289           
00290           fprintf(stderr, "Phase: %5.5f  %5.5f  %5.5f\n", phase1, phase2, phase3);
00291           fprintf(stderr, "Deltas: %5.5f  %5.5f  %5.5f\n", delta1, delta2, delta3);
00292           
00293           // Free Data Array Memory
00294           fftw_free(SP_fft1);
00295           fftw_free(SP_fft2);
00296           fftw_free(SP_fft3);
00297           
00298           // Determine minimum phase difference for pair selection
00299           int min_index = 3;
00300           if (fabs(delta2) < fabs(delta1) && fabs(delta2) < fabs(delta3))
00301             min_index = 2;
00302           if (fabs(delta1) < fabs(delta2) && fabs(delta1) < fabs(delta3))
00303             min_index = 1;
00304           
00305           double delta_tmp;
00306           switch (min_index) {
00307             case 1:
00308               delta_tmp = delta1;
00309               if (delta3 > delta2)
00310                 delta_tmp = -1.0 * delta1 + sign(delta_tmp) * 2.0 * M_PI;
00311               angle_estimate1 = delta_tmp * (double)(((double)target_wavelength1 / 2.0) / SENSOR_SPACING_2_1) * 180.0 / M_PI / 2.0;
00312               break;
00313             case 2:
00314               delta_tmp = delta2;
00315               if (delta1 > delta3)
00316                 delta_tmp = -1.0 * delta2 + 2.0 * M_PI;
00317               angle_estimate1 = (delta_tmp - 4.0 / 3.0 * M_PI) * ((target_wavelength1 / 2.0) / SENSOR_SPACING_3_2) * 180.0 / M_PI / 2.0;
00318               break;
00319             case 3:
00320               delta_tmp = delta3;
00321               if (delta2 > delta1)
00322                 delta_tmp = -1.0 * delta3 - 2.0 * M_PI;
00323               angle_estimate1 = (delta_tmp + 4.0 / 3.0 * M_PI ) * (((double)target_wavelength1 / 2.0) / SENSOR_SPACING_1_3) * 180.0 / M_PI / 2.0;
00324               break;
00325             default:
00326               fprintf(stderr, "Sonar: Invalid min_index for phase difference.");
00327           }
00328           fprintf(stderr, "Min Index: %d\n", min_index);
00329           fprintf(stderr, "Angle Estimate (1): %3.2f\n", angle_estimate1);
00330           
00331           // DEBUG
00332           for (int blah = 0; blah < SP_bin_count * FP_FFT_LENGTH; ++blah)
00333             printf("%5.0f", SP_adc1_samples[blah]);
00334           printf("\n");
00335           
00336         }
00337       }
00338   
00339       if (FP_bin_indicator.size() > FP_BIN_HISTORY_LENGTH)
00340         FP_bin_indicator.erase(FP_bin_indicator.begin());
00341     }
00342   }
00343   fftw_destroy_plan(FP_fft_plan1);
00344   fftw_destroy_plan(FP_fft_plan2);
00345   fftw_destroy_plan(FP_fft_plan3);
00346   fftw_destroy_plan(SP_fft_plan1);
00347   fftw_destroy_plan(SP_fft_plan2);
00348   fftw_destroy_plan(SP_fft_plan3);
00349 
00350   return 0;
00351 }
00352 
Generated on Sun May 8 08:06:37 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3