00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <math.h>
00004 #include <vector>
00005 #include <fftw3.h>
00006
00007
00008
00009 #include "RealData_pinger.H"
00010
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
00022 const double SPEED_SOUND_WATER = 1482;
00023 const double SENSOR_SPACING_2_1 = 0.024;
00024 const double SENSOR_SPACING_3_2 = 0.024;
00025 const double SENSOR_SPACING_1_3 = 0.024;
00026 const int DATA_RETENTION_LENGTH = 1024;
00027
00028
00029
00030 int port, bitrate;
00031
00032
00033
00034
00035 const int FP_FFT_LENGTH = 32;
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
00048
00049 const int TX_LENGTH = 512 * 3 * 2;
00050 uint8_t data_in[TX_LENGTH];
00051 uint8_t data_out[2];
00052
00053
00054 const int FP_BIN_HISTORY_LENGTH = 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
00070 target_frequency1 = 30000;
00071 target_frequency2 = 27000;
00072 target_wavelength1 = (double)SPEED_SOUND_WATER / (double)target_frequency1;
00073 target_wavelength2 = (double)SPEED_SOUND_WATER / (double)target_frequency2;
00074
00075
00076
00077
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
00094
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
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
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
00122 if (adc1_data_history->size() > DATA_RETENTION_LENGTH) {
00123
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
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
00148
00149
00150
00151
00152
00153
00154
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
00160
00161
00162
00163
00164
00165 fftw_execute(FP_fft_plan1);
00166 fftw_execute(FP_fft_plan2);
00167 fftw_execute(FP_fft_plan3);
00168
00169
00170
00171 int FP_target_bin = FP_f1_bin.getTargetBin();
00172
00173
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
00178
00179
00180 if (FP_bin_mean_idx >= FP_BIN_HISTORY_LENGTH)
00181 FP_bin_mean_idx = 0;
00182
00183
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
00219
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
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
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
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
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
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
00270
00271
00272
00273
00274
00275
00276 int SP_target_bin = SP_f1_bin.getTargetBin();
00277
00278 fprintf(stderr, "SP Target Bin: %d\n", SP_target_bin);
00279
00280
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
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
00294 fftw_free(SP_fft1);
00295 fftw_free(SP_fft2);
00296 fftw_free(SP_fft3);
00297
00298
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
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